Contiguous Non-aligned Data Move-in

Applicability

Product

Supported

Atlas 350 Accelerator Card

Atlas A3 training product/Atlas A3 inference product

x

Atlas A2 training product/Atlas A2 inference product

x

Atlas 200I/500 A2 inference product

x

Atlas inference product AI Core

x

Atlas inference product Vector Core

x

Atlas training product

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

Table 1 Parameters for using uint32_t to store the offset in the contiguous non-aligned data move-in mode

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.

Table 2 Parameters for using AddrReg to store the offset in the contiguous non-aligned data move-in mode

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);
}