TROWARGMAX
Instruction Diagram
Introduction
Obtains the column index corresponding to the maximum value in each row, or obtains both the maximum value in each row and its corresponding column index.
Mathematical Semantics
Assume R = src.GetValidRow() and C = src.GetValidCol(). For 0 <= i < R:
Assembly Syntax
Synchronous form:
%dst = trowargmax %src : !pto.tile<...> -> !pto.tile<...>Lowering may introduce internal scratch tiles; the C++ intrinsic requires an explicit tmp operand.
IR Level 1 (SSA)
%dst = pto.trowargmax %src, %tmp : (!pto.tile<...>, !pto.tile<...>) -> !pto.tile<...>IR Level 2 (DPS)
pto.trowargmax ins(%src, %tmp : !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.
Outputs only the index:
template <typename TileDataOut, typename TileDataIn, typename TileDataTmp, typename... WaitEvents>
PTO_INST RecordEvent TROWARGMAX(TileDataOut& dst, TileDataIn& src, TileDataTmp& tmp, WaitEvents&... events);Outputs both the value and the index:
template <typename TileDataOutVal, typename TileDataOutIdx, typename TileDataIn, typename TileDataTmp,
typename... WaitEvents>
PTO_INST RecordEvent TROWARGMAX(TileDataOutVal &dstVal, TileDataOutIdx &dstIdx, TileDataIn &src, TileDataTmp &tmp,
WaitEvents &... events)Constraints
General Constraints or Checks
- Supported source element types:
half,float,int32_t,int16_t(A2A3). A5 accepts any 2/4-byte source (half,bfloat16_t,int16_t,uint16_t,float,int32_t,uint32_t). srcmust use the standard ND layout: row-major and non-fractal (BLayout::RowMajor,SLayout::NoneBox).- When outputting only the index:
dstandsrcmust beTileType::Vec.- Supported destination element types:
uint32_t,int32_t. - Runtime checks follow the shared row reduction check path:
src.GetValidRow() != 0src.GetValidCol() != 0src.GetValidRow() == dst.GetValidRow()
dstis constrained through the shared row reduction index check path and can use any of the following non-fractal layouts:- A single-column DN layout (
BLayout::ColMajor,Cols == 1), or - An ND layout with a valid column count of 1.
- A single-column DN layout (
- When outputting both the value and index:
dstVal,dstIdx, andsrcmust beTileType::Vec.- The element type of
dstValmust be the same as the element type ofsrc. - Supported destination element types:
- When the source element type is
float,uint32_tandint32_tare supported. - When the source element type is
half,uint16_tandint16_tare supported.
- When the source element type is
- The runtime check follows the shared row reduction check path:
src.GetValidRow() != 0src.GetValidCol() != 0src.GetValidRow() == dstIdx.GetValidRow()src.GetValidRow() == dstVal.GetValidRow()
dstValanddstIdxare constrained through the shared row reduction index check path, and can use any of the following non-fractal layouts:- A single column DN layout (
BLayout::ColMajor,Cols == 1), or - An ND layout with a valid column count of 1.
- A single column DN layout (
tmp Tile Description
- Only Atlas A2/A3 training products/Atlas A2/A3 inference products use the
tmptile. Ascend 950PR/Ascend 950DT receivetmpbut do not actually use it. - The implementation of Atlas A2/A3 training products/Atlas A2/A3 inference products selects one of three code paths based on the relationship between
srcValidColandelementPerRepeat(abbreviated aselemPerRpt):
Case 1: srcValidCol <= elemPerRpt
- Index-only mode:
tmpis not used. The hardwarevcmaxinstruction writes directly todst. - Value+index mode:
tmpis used as a small buffer (2 elements per row: one value + one index).tmpcan use either of the following non-fractal layouts:- Single-column DN layout (
BLayout::ColMajor,Cols == 1), with a valid row count ofsrcValidRow * 2. - ND layout with a valid row count of
srcValidRowand a valid column count of 2.
- Single-column DN layout (
Case 2: elemPerRpt < srcValidCol <= elemPerRpt² (Single-Stage Reduction)
tmpis used for single-stage reduction.- The number of rows of the
tmptile is the same as that ofsrc. - The stride required for each row of the
tmptile is calculated using the following formula:
R1 = ceil(validCol / elemPerRpt)
stride = (ceil(R1 * 2 / elemPerBlock) + ceil(R1 / elemPerBlock)) * elemPerBlockCase 3: srcValidCol > elemPerRpt² (Two-Stage Reduction)
tmpis used for two-stage reduction, requiring more space than single-stage.- The number of rows of the
tmptile is the same as that ofsrc. - The stride required for each row of the
tmptile is calculated using the following formula:
R1 = ceil(validCol / elemPerRpt)
R2 = ceil(R1 / elemPerRpt)
stage1_size = ceil(R1 * 2 / elemPerBlock) * elemPerBlock
stage2_end = ceil(R1 / elemPerBlock) * elemPerBlock + ceil(R2 * 2 / elemPerBlock) * elemPerBlock
stride = max(stage1_size, stage2_end) + 2+ 2is used to store the final value + index result at the end of each row's tmp region.
Examples
Automatic
#include <pto/pto-inst.hpp>
using namespace pto;
void example_auto() {
using SrcT = Tile<TileType::Vec, float, 16, 16>;
using DstT = Tile<TileType::Vec, uint32_t, 16, 1, BLayout::ColMajor>;
using DstValT = Tile<TileType::Vec, float, 16, 1, BLayout::ColMajor>;
using TmpT = Tile<TileType::Vec, float, 16, 16>;
SrcT src;
DstT dst;
DstValT dstVal;
TmpT tmp;
TROWARGMAX(dst, src, tmp);
TROWARGMAX(dstVal, dst, src, 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, uint32_t, 16, 1, BLayout::ColMajor>;
using DstValT = Tile<TileType::Vec, float, 16, 1, BLayout::ColMajor>;
using TmpT = Tile<TileType::Vec, float, 16, 16>;
SrcT src;
DstT dstIdx;
DstValT dstVal;
TmpT tmp;
TASSIGN(src, 0x1000);
TASSIGN(dstIdx, 0x2000);
TASSIGN(dstVal, 0x3000);
TASSIGN(tmp, 0x4000);
TROWARGMAX(dstIdx, src, tmp);
TROWARGMAX(dstVal, dstIdx, src, tmp);
}ASM Examples
Automatic Mode
# Automatic mode: the compiler/runtime handles resource placement and scheduling.
%dst = pto.trowargmax %src, %tmp : (!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.trowargmax %src, %tmp : (!pto.tile<...>, !pto.tile<...>) -> !pto.tile<...>PTO Assembly Form
%dst = trowargmax %src : !pto.tile<...> -> !pto.tile<...>
# IR Level 2 (DPS)
pto.trowargmax ins(%src, %tmp : !pto.tile_buf<...>, !pto.tile_buf<...>) outs(%dst : !pto.tile_buf<...>)