Contiguous Non-aligned Data Move-in
Applicability
Product |
Supported |
|---|---|
Atlas 350 Accelerator Card |
√ |
x |
|
x |
|
x |
|
x |
|
x |
|
x |
Function Usage
Indicates the Reg vector computation data movement interface, and is used to contiguously move data from a non-32B aligned address in UB to RegTensor.
Prototype
// The LoadUnAlignPre interface is used for initialization before non-aligned data movement, and is applicable to scenarios 1 and 2. template <typename T> __simd_callee__ inline void LoadUnAlignPre(UnalignRegForLoad& ureg, __ubuf__ T* srcAddr); // The LoadUnAlignPre interface is used for initialization before non-aligned data movement, and is applicable to scenario 3. template <typename T> __simd_callee__ inline void LoadUnAlignPre(UnalignRegForLoad& ureg, __ubuf__ T* srcAddr, AddrReg& areg); // Scenario 1: Use uint32_t as the offset and use the post mode for data movement. The address of the source operand in the UB is updated each time the API is called. template <typename T = DefaultType, PostLiteral postMode = PostLiteral::POST_MODE_UPDATE, typename U> __simd_callee__ inline void LoadUnAlign(U& dstReg, UnalignRegForLoad& ureg, __ubuf__ T*& srcAddr, uint32_t postUpdateStride); // Scenario 2: The address of the source operand in the UB is not changed when the API is called. The address of the source operand in the UB needs to be manually updated for each repeat. template <typename T = DefaultType, typename U> __simd_callee__ inline void LoadUnAlign(U& dstReg, UnalignRegForLoad& ureg, __ubuf__ T* srcAddr); // Scenario 3: Use AddrReg to store the offset for data movement. template <typename T = DefaultType, typename U> __simd_callee__ inline void LoadUnAlign(U& dstReg, UnalignRegForLoad& ureg, __ubuf__ T*& srcAddr, AddrReg& areg, uint32_t inc);
Parameters
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. |
U |
Input |
Template parameter. The corresponding RegTensor type for the supported data types. |
ureg |
Input/Output |
UnalignRegForLoad: non-aligned register, which is used to store non-aligned data. The length is 32 bytes. It is used as an output in the LoadUnAlignPre function and as an input or output in the LoadUnAlign function. |
dstReg |
Output |
Destination operand, which is of the RegTensor type. |
srcAddr |
Input/Output |
Start address of the source operand in the UB. |
postUpdateStride |
Input |
Only the POST_MODE_UPDATE scenario is supported. The actual UB start address for moving data is srcAddr. After the movement, the address is updated as follows: srcAddr += postUpdateStride. |
Parameter |
Input/Output |
Description |
|---|---|---|
ureg |
Input/Output |
UnalignRegForLoad: non-aligned register, which is used to store non-aligned data. The length is 32 bytes. It is used as an output in the LoadUnAlignPre function and as an input or output in the LoadUnAlign function. |
dstReg |
Output |
Destination operand, which is of the RegTensor type. |
srcAddr |
Input/Output |
Start address of the source operand in the UB. |
areg |
Input |
AddrReg data type, which stores the address offset. The actual UB start address for the movement is computed as: srcAddr + offset. |
inc |
Input |
After the movement is complete, the offset is updated to offset + inc, before being incremented. |
Restrictions
- The srcAddr parameter in this API does not need to be 32-byte aligned.
- The LoadUnAlignPre and LoadUnAlign interfaces must be used together.
Examples
// Use uint32_t to store the offset in the contiguous non-aligned data move-in mode.
template <typename T>
__simd_vf__ inline void LoadUnAlignVF(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint32_t postUpdateStride, uint16_t repeatTimes)
{
AscendC::Reg::RegTensor<T> srcReg;
AscendC::Reg::UnalignRegForLoad ureg0;
AscendC::Reg::UnalignRegForStore ureg1;
for (uint16_t i = 0; i < repeatTimes; ++i) {
AscendC::Reg::LoadUnAlignPre(ureg0, srcAddr + i * postUpdateStride);
AscendC::Reg::LoadUnAlign(srcReg, ureg0, srcAddr + i * postUpdateStride);
AscendC::Reg::StoreUnAlign(dstAddr, srcReg, ureg1, postUpdateStride);
}
AscendC::Reg::StoreUnAlignPost(dstAddr, ureg1, 0);
}
// Use AddrReg to store the offset in the contiguous non-aligned data move-in mode.
template <typename T>
__simd_vf__ inline void LoadUnAlignVF(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint32_t oneRepeatSize, uint16_t repeatTimes)
{
AscendC::Reg::RegTensor<T> srcReg;
AscendC::Reg::UnalignRegForLoad ureg0;
AscendC::Reg::UnalignRegForStore ureg1;
AscendC::Reg::AddrReg aReg;
for (uint16_t i = 0; i < repeatTimes; ++i) {
aReg = AscendC::Reg::CreateAddrReg<T>(i, oneRepeatSize);
AscendC::Reg::LoadUnAlignPre(ureg0, srcAddr, aReg);
AscendC::Reg::LoadUnAlign(srcReg, ureg0, srcAddr, aReg, 0);
AscendC::Reg::StoreUnAlign(dstAddr, srcReg, ureg1, aReg);
}
AscendC::Reg::StoreUnAlignPost(dstAddr, ureg1, aReg);
}