Reduce
Applicability
Product |
Supported |
|---|---|
Atlas 350 Accelerator Card |
√ |
x |
|
x |
|
x |
|
x |
|
x |
|
x |
Function Usage
Supports sum reduction, max reduction, and min reduction.
Prototype
template <ReduceType type = ReduceType::SUM, typename T = DefaultType, typename U = DefaultType, MaskMergeMode mode = MaskMergeMode::ZEROING, typename S, typename V> __simd_callee__ inline void Reduce(S& dstReg, V srcReg, MaskReg mask)
Parameters
Parameter |
Description |
|---|---|
type |
ReduceType type. SUM, MAX, and MIN are supported. enum class ReduceType {
SUM = 0,
MAX,
MIN,
};
|
T |
Data type of the destination operand dstReg.
|
U |
Data type of the source operand srcReg.
For the Atlas 350 Accelerator Card, the supported data types are int16_t, half, int32_t, float, uint16_t, uint32_t, uint64_t, and int64_t. |
mode |
Set it to MERGING or ZEROING. Currently, only ZEROING is supported.
|
S |
RegTensor type of the destination operand, for example, RegTensor<half>. It is automatically inferred by the compiler and does not need to be specified. |
V |
RegTensor type of the source operand, for example, RegTensor<half>. It is automatically inferred by the compiler and does not need to be specified. |
Constraints
- For max reduction, if no element is involved in the computation, the minimum value of the data type is written to dstReg. If there are multiple maximum values, the index of the first maximum value is stored in dstReg.
- For min reduction, if no element is involved in the computation, the maximum value of the data type is written to dstReg. If there are multiple minimum values, the index of the first minimum value is stored in dstReg.
- When the reduction operation is used to compute the minimum or maximum value, the source operand must have the same data type as the destination operand.
Example
- Sum reduction:
template<typename T, typename U> __simd_vf__ inline void ReduceVF(__ubuf__ T* dstAddr, __ubuf__ U* srcAddr, uint32_t count, uint32_t srcRepeatSize, uint32_t dstRepeatSize, uint16_t repeatTimes) { AscendC::Reg::RegTensor<U> srcReg; AscendC::Reg::RegTensor<T> dsrReg; AscendC::Reg::MaskReg mask; for (uint16_t i = 0; i < repeatTimes; i++) { AscendC::Reg::LoadAlign(srcReg, srcAddr + i * srcRepeatSize); mask = AscendC::Reg::UpdateMask<U>(count); AscendC::Reg::Reduce<AscendC::Reg::ReduceType::SUM>(dsrReg, srcReg, mask); AscendC::Reg::StoreAlign(dstAddr + i * dstRepeatSize, dsrReg, mask); } } - Max or min reduction:
template<typename T> __aicore__ inline void ReduceVF(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint32_t count, uint32_t oneRepeatSize, uint16_t repeatTimes) { AscendC::Reg::RegTensor<T> srcReg; AscendC::Reg::RegTensor<T> dstReg; AscendC::Reg::MaskReg mask; for (uint16_t i = 0; i < repeatTimes; i++) { AscendC::Reg::LoadAlign(srcReg, srcAddr + i * oneRepeatSize); mask = AscendC::Reg::UpdateMask<T>(count); // type = ReduceType::MAX AscendC::Reg::Reduce<AscendC::Reg::ReduceType::MAX>(dstReg, srcReg, mask); // type = ReduceType::MIN // AscendC::Reg::Reduce<AscendC::Reg::ReduceType::MIN>(dstReg, srcReg, mask); AscendC::Reg::StoreAlign(dstAddr + i * oneRepeatSize, dstReg, maskReg); } }