Contiguous Aligned Data Move-in
Applicability
Product |
Supported |
|---|---|
Atlas 350 Accelerator Card |
√ |
x |
|
x |
|
x |
|
x |
|
x |
|
x |
Function Usage
Reg vector computation data movement interface, used to move contiguous aligned data from UB to RegTensor. In the single move-in mode, data can be moved from UB to one destination register. In the double move-in mode, data can be moved from UB to two destination registers.
Prototype
// Under the POST_MODE_NORMAL scenario, the single move-in mode is utilized. template <typename T = DefaultType, LoadDist dist = LoadDist::DIST_NORM, typename U> __simd_callee__ inline void LoadAlign(U& dstReg, __ubuf__ T* srcAddr); // Under the POST_MODE_UPDATE scenario, the single move-in mode is utilized. template <typename T = DefaultType, PostLiteral postMode, LoadDist dist = LoadDist::DIST_NORM, typename U> __simd_callee__ inline void LoadAlign(U& dstReg, __ubuf__ T*& srcAddr, int32_t postUpdateStride); // Use AddrReg to store the offset in the single move-in mode. template <typename T = DefaultType, LoadDist dist = LoadDist::DIST_NORM, typename U> __simd_callee__ inline void LoadAlign(U& dstReg, __ubuf__ T* srcAddr, AddrReg offset); // Under the POST_MODE_NORMAL scenario, the double move-in mode is utilized. template <typename T = DefaultType, LoadDist dist, typename U> __simd_callee__ inline void LoadAlign(U& dstReg0, U& dstReg1, __ubuf__ T* srcAddr); // Under the POST_MODE_UPDATE scenario, the double move-in mode is utilized. template <typename T = DefaultType, PostLiteral postMode, LoadDist dist, typename U> __simd_callee__ inline void LoadAlign(U& dstReg0, U& dstReg1, __ubuf__ T*& srcAddr, int32_t postUpdateStride); // Use AddrReg to store the offset in the double move-in mode. template <typename T = DefaultType, LoadDist dist, typename U> __simd_callee__ inline void LoadAlign(U& dstReg0, U& dstReg1, __ubuf__ T* srcAddr, AddrReg offset);
Parameters
LoadDist Value |
Description |
Movement Alignment Constraint (Byte) |
|---|---|---|
DIST_NORM |
Normal mode. VL data is moved. |
32 |
DIST_BRC_B8 |
A piece of data of b8 type is moved and broadcast to all element positions. |
1 |
DIST_BRC_B16 |
A piece of data of b16 type is moved and broadcast to all element positions. |
2 |
DIST_BRC_B32 |
A piece of data of b32 type is moved and broadcast to all element positions. |
4 |
DIST_US_B8 |
Data is upsampled by a factor of 2, and VL/2 data elements are loaded. Each input element is repeated twice, and the data type is b8. |
min(32, VL/2) |
DIST_US_B16 |
Data is upsampled by a factor of 2, and VL/2 data elements are loaded. Each input element is repeated twice, and the data type is b16. |
min(32, VL/2) |
DIST_DS_B8 |
Data is downsampled by a factor of 2, and 2x VL data is loaded. Every other data element is retained, and the data type is b8. |
32 |
DIST_DS_B16 |
Data is downsampled by a factor of 2, and 2x VL data is loaded. Every other data element is retained, and the data type is b16. |
32 |
DIST_UNPACK_B8 |
Unpack mode: Load VL/2 elements of u8 data, unpack to u16 format with a length of VL, and insert zeros in the middle positions. Example: VL = 256B: src: [0x00, 0x01, 0x02, 0x03, ..., 0xFF, ...] dst:[0x0000, 0x0001, ..., 0x0007F] |
min(32, VL/2) |
DIST_UNPACK_B16 |
Unpack mode: Load VL/2 elements of u16 data, unpack to u32 format with a length of VL, and insert zeros in the middle positions. Example: VL = 256B: src: [0x0000, 0x0001, 0x0002, 0x0003, ..., 0x007F, ...] dst:[0x00000000, 0x00000001, ..., 0x000003F] |
min(32, VL/2) |
DIST_BLK |
A data block (32 bytes) is read and sent to the VL. |
32 |
DIST_E2B_B16 |
Data is loaded from (VL/Data block) B, and each 16-bit element is broadcast into a 32-byte data block. |
VL/16 |
DIST_E2B_B32 |
Data is loaded from (VL/Data block) B, and each 32-bit element is broadcast into a 32-byte data block. |
VL/8 |
DIST_UNPACK_B32 |
Unpack mode: Load VL/2 elements of u32 data, unpack to u64 format with a length of VL, and insert zeros in the middle positions. Example: VL = 256B: src: [0x00000000, 0x00000001, 0x00000002, ..., 0x000003F, ...] dst:[0x0000000000000000, 0x0000000000000001, ..., 0x000000000000001F] |
min(32, VL/2) |
DIST_UNPACK4_B8 |
Unpack mode: Load VL/4 elements of u8 data, unpack to u32 format with a length of VL, and insert zeros in the middle positions. Example: VL = 256B: src: [0x00, 0x01, 0x02, 0x03, ..., 0xFF, ...] dst:[0x00000000, 0x00000001, ..., 0x000003F] |
min(32, VL/4) |
LoadDist Value |
Description |
Movement Alignment Constraint (Byte) |
|---|---|---|
DIST_DINTLV_B8 |
In the double move-in mode, perform element-based interleaved movement. Read data of length 2 x VL from src, store the elements with even indexes to dst0, and store the elements with odd indexes to dst1. The data type is b8. |
32 |
DIST_DINTLV_B16 |
In the double move-in mode, perform element-based interleaved movement. Read data of length 2 x VL from src, store the elements with even indexes to dst0, and store the elements with odd indexes to dst1. The data type is b16. |
32 |
DIST_DINTLV_B32 |
In the double move-in mode, perform element-based interleaved movement. Read data of length 2 x VL from src, store the elements with even indexes to dst0, and store the elements with odd indexes to dst1. The data type is b32. |
32 |
Parameter |
Input/Output |
Description |
|---|---|---|
T |
Input |
Operand data type. The supported data types are b8, b16, b32, and b64. |
dist |
Input |
Movement mode, which is of the LoadDist type. For details about the value, see Table 1. |
U |
Input |
RegTensor type of the destination operand, for example, RegTensor<half>. It is automatically inferred by the compiler and does not need to be specified. |
dstReg |
Output |
Destination operand, which is of the RegTensor type. |
srcAddr |
Input |
Start address of the source operand in the UB. |
Parameter |
Input/Output |
Description |
|---|---|---|
T |
Input |
Template parameter. The supported data types are b8, b16, b32, and b64. |
postMode |
Input |
This parameter controls whether to enable post update. The value is of the PostLiteral type. |
dist |
Input |
Movement mode, which is of the LoadDist type. For details about the value, see Table 1. |
U |
Input |
RegTensor type of the destination operand, for example, RegTensor<half>. It is automatically inferred by the compiler and does not need to be specified. |
dstReg |
Output |
Destination operand, which is of the RegTensor type. |
srcAddr |
Input/Output |
Start address of the source operand in the UB. |
postUpdateStride |
Input |
The actual start address for moving data to the UB is srcAddr. After the movement, the address is updated as follows: srcAddr += postUpdateStride. |
Parameter |
Input/Output |
Description |
|---|---|---|
T |
Input |
Template parameter. The supported data types are b8, b16, b32, and b64. |
dist |
Input |
Movement mode, which is of the LoadDist type. For details about the value, see Table 1. |
U |
Input |
RegTensor type of the destination operand, for example, RegTensor<half>. It is automatically inferred by the compiler and does not need to be specified. |
dstReg |
Output |
Destination operand, which is of the RegTensor type. |
offset |
Input |
The actual movement address UB is computed by adding the source address (srcAddr) and the offset. |
srcAddr |
Input/Output |
Start address of the source operand in the UB. |
Parameter |
Input/Output |
Description |
|---|---|---|
T |
Input |
Template parameter. The supported data types are b8, b16, and b32. |
dist |
Input |
Movement mode, which is of the LoadDist type. For details about the value, see Table 2. |
U |
Input |
RegTensor type of the destination operand, for example, RegTensor<half>. It is automatically inferred by the compiler and does not need to be specified. |
dstReg0 |
Output |
The first destination operand, which is of the RegTensor type. |
dstReg1 |
Output |
The second destination operand, which is of the RegTensor type. |
srcAddr |
Input/Output |
Start address of the source operand in the UB. |
Parameter |
Input/Output |
Description |
|---|---|---|
T |
Input |
Template parameter. The supported data types are b8, b16, b32, and b64. |
postMode |
Input |
This parameter controls whether to enable post update. The value is of the PostLiteral type. |
dist |
Input |
Movement mode, which is of the LoadDist type. For details about the value, see Table 2. |
U |
Input |
RegTensor type of the destination operand, for example, RegTensor<half>. It is automatically inferred by the compiler and does not need to be specified. |
dstReg0 |
Output |
The first destination operand, which is of the RegTensor type. |
dstReg1 |
Output |
The second destination operand, which is of the RegTensor type. |
srcAddr |
Input/Output |
Start address of the source operand in the UB. |
postUpdateStride |
Input |
The actual start address for moving data to the UB is srcAddr. After the movement, the address is updated as follows: srcAddr += postUpdateStride. |
Parameter |
Input/Output |
Description |
|---|---|---|
T |
Input |
Template parameter. The supported data types are b8, b16, and b32. |
dist |
Input |
Movement mode, which is of the LoadDist type. For details about the value, see Table 2. |
U |
Input |
RegTensor type of the destination operand, for example, RegTensor<half>. It is automatically inferred by the compiler and does not need to be specified. |
dstReg0 |
Output |
The first destination operand, which is of the RegTensor type. |
dstReg1 |
Output |
The second destination operand, which is of the RegTensor type. |
offset |
Input |
The actual movement address UB is computed by adding the source address (srcAddr) and the offset. |
srcAddr |
Input/Output |
Start address of the source operand in the UB. |
Returns
None
Restrictions
The b64 data type supports only the DIST_NORM mode in LoadDist.
Examples
// Use POST_MODE_NORMAL in the single move-in or single move-out mode.
__simd_vf__ inline void ComputeMode01(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint32_t dstSize,
uint32_t oneRepeatSize, uint16_t repeatTimes)
{
AscendC::Reg::RegTensor<T> dstReg;
AscendC::Reg::MaskReg mask;
for (uint16_t i = 0; i < repeatTimes; ++i) {
mask = AscendC::Reg::UpdateMask<T>(dstSize);
AscendC::Reg::LoadAlign(dstReg, srcAddr + i * oneRepeatSize);
AscendC::Reg::StoreAlign(dstAddr + i * oneRepeatSize, dstReg, mask);
}
}
// Use POST_MODE_UPDATE in the single move-in or single move-out mode.
__simd_vf__ inline void ComputeMode02(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint32_t dstSize,
uint32_t oneRepeatSize, uint16_t repeatTimes)
{
AscendC::Reg::RegTensor<T> dstReg;
AscendC::Reg::MaskReg mask;
for (uint16_t i = 0; i < repeatTimes; ++i) {
mask = AscendC::Reg::UpdateMask<T>(dstSize);
AscendC::Reg::LoadAlign<T, AscendC::Reg::PostLiteral::POST_MODE_UPDATE>(dstReg, srcAddr, oneRepeatSize);
AscendC::Reg::StoreAlign<T, AscendC::Reg::PostLiteral::POST_MODE_UPDATE>(dstAddr, dstReg, oneRepeatSize, mask);
}
}
// Use AddrReg to store the offset in the single move-in or single move-out mode.
__simd_vf__ inline void ComputeMode03(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint32_t oneRepeatSize, uint16_t repeatTimes)
{
AscendC::Reg::RegTensor<T> dstReg;
AscendC::Reg::MaskReg mask = AscendC::Reg::CreateMask<T>();
AscendC::Reg::AddrReg aReg;
for (uint16_t i = 0; i < repeatTimes; ++i) {
aReg = AscendC::Reg::CreateAddrReg<T>(i, oneRepeatSize);
AscendC::Reg::LoadAlign(dstReg, srcAddr, aReg);
AscendC::Reg::StoreAlign(dstAddr, dstReg, aReg, mask);
}
}
// Use POST_MODE_NORMAL in the double move-in or double move-out mode.
__simd_vf__ inline void ComputeMode04(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint32_t oneRepeatSize,
uint16_t repeatTimes)
{
AscendC::Reg::RegTensor<T> srcReg0;
AscendC::Reg::RegTensor<T> srcReg1;
AscendC::Reg::MaskReg mask = AscendC::Reg::CreateMask<uint8_t, AscendC::Reg::MaskPattern::ALL>();
for (uint16_t i = 0; i < repeatTimes; ++i) {
AscendC::Reg::LoadAlign<T, AscendC::Reg::LoadDist::DIST_DINTLV_B8>(srcReg0, srcReg1, srcAddr + i * oneRepeatSize);
AscendC::Reg::StoreAlign<T, AscendC::Reg::StoreDist::DIST_INTLV_B8>(dstAddr + i * oneRepeatSize, srcReg0, srcReg1, mask);
}
}
// Use AddrReg to store the offset in the double move-in or double move-out mode.
__simd_vf__ inline void ComputeMode05(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint32_t oneRepeatSize, uint16_t repeatTimes)
{
AscendC::Reg::RegTensor<T> srcReg0;
AscendC::Reg::RegTensor<T> srcReg1;
AscendC::Reg::MaskReg mask = AscendC::Reg::CreateMask<T>();
AscendC::Reg::AddrReg aReg;
for (uint16_t i = 0; i < repeatTimes; ++i) {
aReg = AscendC::Reg::CreateAddrReg<T>(i, oneRepeatSize);
AscendC::Reg::LoadAlign<T, AscendC::Reg::LoadDist::DIST_DINTLV_B8>(srcReg0, srcReg1, srcAddr, aReg);
AscendC::Reg::StoreAlign<T, AscendC::Reg::StoreDist::DIST_INTLV_B8>(dstAddr, srcReg0, srcReg1, aReg, mask);
}
}