TDEINTERLEAVE
Instruction Diagram
Introduction
Deinterleaves a source tile into two destination tiles (dst0 and dst1). This operation reverses the interleaving process: dst0 receives the even position elements of the interleaved stream, and dst1 receives the odd position elements.
TDeInterleave has two overloaded forms:
- Dual-source form (
dst1, dst0, src1, src0): Given two source tiles that hold the first half and the second half of the interleaved stream, deinterleaves them into the original even element stream and odd element stream. - Single-source form (
dst1, dst0, src): Given a single source tile that contains the complete interleaved data, deinterleaves it into even position and odd position element streams. Each destination row holdssrc.GetValidCol() / 2valid elements.
TDeInterleave is the inverse operation of TInterleave.
Mathematical Semantics
Dual-Source Form
Given two source tiles src0 (first half) and src1 (second half), reconstruct the complete interleaved stream and deinterleave it:
Where validRows = dst0.GetValidRow() and validCols = dst0.GetValidCol().
Single-Source Form
Given a source tile src containing row-wise interleaved data:
Where halfValidCols = src.GetValidCol() / 2.
Note: The single-source form requires the source tile to have a row width of at least
2 × ElementsPerRepeatelements (whereElementsPerRepeat = 256 / sizeof(T), that is,2 × sregLower), to ensure that the two adjacent register-sized data blocks loaded in each repeat do not cross a row boundary.
Assembly Syntax
Synchronous form (dual-source):
%dst0, %dst1 = tdeinterleave %src0, %src1 : !pto.tile<...>Synchronous form (single-source):
%dst0, %dst1 = tdeinterleave %src : !pto.tile<...>AS Level 1 (SSA)
Dual-source form:
%dst0, %dst1 = pto.tdeinterleave %src0, %src1 : (!pto.tile<...>, !pto.tile<...>) -> (!pto.tile<...>, !pto.tile<...>)Single-source form:
%dst0, %dst1 = pto.tdeinterleave %src : (!pto.tile<...>) -> (!pto.tile<...>, !pto.tile<...>)AS Level 2 (DPS)
Dual-source form:
pto.tdeinterleave ins(%src0, %src1 : !pto.tile_buf<...>, !pto.tile_buf<...>) outs(%dst0, %dst1 : !pto.tile_buf<...>, !pto.tile_buf<...>)Single-source form:
pto.tdeinterleave ins(%src : !pto.tile_buf<...>) outs(%dst0, %dst1 : !pto.tile_buf<...>, !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.
// dual-source form
template <typename TileDataDst, typename TileDataSrc, typename... WaitEvents>
PTO_INST RecordEvent TDeInterleave(TileDataDst &dst1, TileDataDst &dst0, TileDataSrc &src1, TileDataSrc &src0,
WaitEvents &...events);
// single-source form
template <typename TileDataDst, typename TileDataSrc, typename... WaitEvents>
PTO_INST RecordEvent TDeInterleave(TileDataDst &dst1, TileDataDst &dst0, TileDataSrc &src,
WaitEvents &...events);Note: The parameter order of the dual-source form is
(dst1, dst0, src1, src0).dst0receives the even-position elements of the interleaved stream, anddst1receives the odd-position elements.
Constraints
- Implementation check (Ascend 950PR/Ascend 950DT):
TileData::DTypemust be one of the following:int32_t,uint32_t,float,int16_t,uint16_t,half,bfloat16_t,uint8_t,int8_t.- The tile layout must be row-major (
TileData::isRowMajor). - All tiles must have the same
DType. - Dual-source form:
src0,src1,dst0, anddst1must have the same valid shape, and their validCols must be even. - Single-source form:
src,dst0, anddst1must have the same number of valid rows; thevalidColsofdst0anddst1must be half of thevalidColsofsrc.
- Valid region:
- Dual-source form: this operation uses
dst0.GetValidRow()/dst0.GetValidCol()as the iteration domain. Each row ofdst0/dst1holdsvalidColselements. - Single-source form: each row of
dst0/dst1holdssrc.GetValidCol() / 2valid elements. Elements beyondhalfValidColsin each row are unspecified.
- Dual-source form: this operation uses
Examples
Automatic — Dual-Source Form
#include <pto/pto-inst.hpp>
using namespace pto;
void example_auto_two_src() {
using TileT = Tile<TileType::Vec, float, 16, 128>;
TileT src0(16, 128), src1(16, 128);
TileT dst0(16, 128), dst1(16, 128);
TDeInterleave(dst1, dst0, src1, src0);
}Automatic — Single-Source Form
#include <pto/pto-inst.hpp>
using namespace pto;
void example_auto_single_src() {
using TileT = Tile<TileType::Vec, float, 16, 128>;
TileT src(16, 128);
TileT dst0(16, 128), dst1(16, 128);
TDeInterleave(dst1, dst0, src);
}Manual — Dual-Source Form
#include <pto/pto-inst.hpp>
using namespace pto;
void example_manual_two_src() {
using TileT = Tile<TileType::Vec, half, 16, 256, BLayout::RowMajor, 16, 256>;
TileT src0, src1, dst0, dst1;
TASSIGN(src0, 0x1000);
TASSIGN(src1, 0x2000);
TASSIGN(dst0, 0x3000);
TASSIGN(dst1, 0x4000);
TDeInterleave(dst1, dst0, src1, src0);
}Manual — Single-Source Form
#include <pto/pto-inst.hpp>
using namespace pto;
void example_manual_single_src() {
using TileT = Tile<TileType::Vec, half, 16, 256, BLayout::RowMajor, 16, 256>;
TileT src, dst0, dst1;
TASSIGN(src, 0x1000);
TASSIGN(dst0, 0x2000);
TASSIGN(dst1, 0x3000);
TDeInterleave(dst1, dst0, src);
}ASM Examples
Automatic Mode
# Automatic mode: the compiler/runtime handles resource placement and scheduling.
# Dual-source form:
%dst0, %dst1 = pto.tdeinterleave %src0, %src1 : (!pto.tile<...>, !pto.tile<...>) -> (!pto.tile<...>, !pto.tile<...>)
# Single-source form:
%dst0, %dst1 = pto.tdeinterleave %src : (!pto.tile<...>) -> (!pto.tile<...>, !pto.tile<...>)Manual Mode
# Manual mode: explicitly bind resources first, then issue the instruction.
# Dual-source form:
# pto.tassign %src0, @tile(0x1000)
# pto.tassign %src1, @tile(0x2000)
# pto.tassign %dst0, @tile(0x3000)
# pto.tassign %dst1, @tile(0x4000)
%dst0, %dst1 = pto.tdeinterleave %src0, %src1 : (!pto.tile<...>, !pto.tile<...>) -> (!pto.tile<...>, !pto.tile<...>)
# Single-source form:
# pto.tassign %src, @tile(0x1000)
# pto.tassign %dst0, @tile(0x2000)
# pto.tassign %dst1, @tile(0x3000)
%dst0, %dst1 = pto.tdeinterleave %src : (!pto.tile<...>) -> (!pto.tile<...>, !pto.tile<...>)PTO Assembly Form
# Dual-source form:
%dst0, %dst1 = tdeinterleave %src0, %src1 : !pto.tile<...>
# AS Level 2 (DPS)
pto.tdeinterleave ins(%src0, %src1 : !pto.tile_buf<...>, !pto.tile_buf<...>) outs(%dst0, %dst1 : !pto.tile_buf<...>, !pto.tile_buf<...>)
# Single-source form:
%dst0, %dst1 = tdeinterleave %src : !pto.tile<...>
# AS Level 2 (DPS)
pto.tdeinterleave ins(%src : !pto.tile_buf<...>) outs(%dst0, %dst1 : !pto.tile_buf<...>, !pto.tile_buf<...>)Related Instructions
- TInterleave - Interleaves two tiles into alternating even/odd streams (the inverse operation of TDeInterleave).