asc_vf_call
Applicability
Product |
Supported |
|---|---|
Atlas 350 Accelerator Card |
√ |
x |
|
x |
|
x |
|
x |
|
x |
|
x |
Function Usage
Is used in SIMD programming scenarios to start SIMD vector function (VF) subtasks.
When using asc_vf_call to start SIMD VF subtasks, the subtask function must not be a class member function. Using ordinary functions or static class functions is recommended, and the entry function must be marked with the __simd_vf__ macro.
When using asc_vf_call to start SIMD VF subtasks, only raw pointers and common basic data types can be passed as parameters. Structures and arrays cannot be passed.
Prototype
1 2 | template <auto funcPtr, typename... Args> __aicore__ inline void asc_vf_call(Args &&...args) |
Parameters
Parameter |
Description |
|---|---|
funcPtr |
Specifies the SIMD entry kernel function. |
Args |
Defines a variable parameter list to pass parameters to the SIMD entry kernel function. |
Parameter |
Input/Output |
Description |
|---|---|---|
args |
Input |
Defines a variable parameter list to pass parameters to the SIMD entry kernel function. |
Returns
None
Restrictions
None
Examples
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // SIMD function __simd_vf__ inline void AddVF(__ubuf__ float* dstAddr, __ubuf__ float* src0Addr, __ubuf__ float* src1Addr, uint32_t count, uint32_t oneRepeatSize, uint16_t repeatTimes) { AscendC::Reg::RegTensor<float> srcReg0; AscendC::Reg::RegTensor<float> srcReg0; AscendC::Reg::RegTensor<float> dstReg; AscendC::Reg::MaskReg mask; for (uint16_t i = 0; i < repeatTimes; ++i) { mask = AscendC::Reg::UpdateMask<float>(count); AscendC::Reg::LoadAlign(srcReg0, src0Addr + i * oneRepeatSize); AscendC::Reg::LoadAlign(srcReg1, src1Addr + i * oneRepeatSize); AscendC::Reg::Add(dstReg, srcReg0, srcReg1, mask); AscendC::Reg::StoreAlign(dstAddr + i * oneRepeatSize, dstReg , mask); } } __aicore__ inline void SimdComputeShell() { AscendC::LocalTensor<float> dst = outQueueZ.AllocTensor<float>(); AscendC::LocalTensor<float> src0 = inQueueX.DeQue<float>(); AscendC::LocalTensor<float> src1 = inQueueY.DeQue<float>(); constexpr uint32_t oneRepeatSize = AscendC::GetVecLen()/sizeof(float); uint32_t count = 512; // Round up and compute repeat. uint16_t repeatTimes = AscendC::CeilDivision(count, oneRepeatSize); __ubuf__ float* dstAddr = (__ubuf__ float*)dst.GetPhyAddr(); __ubuf__ float* src0Addr = (__ubuf__ float*)src0.GetPhyAddr(); __ubuf__ float* src1Addr = (__ubuf__ float*)src1.GetPhyAddr(); asc_vf_call<AddVF>(dstAddr, src0Addr, src1Addr, count, oneRepeatSize, repeatTimes); outQueueZ.EnQue(dst); inQueueX.FreeTensor(src0); inQueueY.FreeTensor(src1); } |