| #include "edge-impulse-sdk/dsp/config.hpp" |
| #if EIDSP_LOAD_CMSIS_DSP_SOURCES |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include "edge-impulse-sdk/CMSIS/DSP/Include/dsp/statistics_functions.h" |
| #include <limits.h> |
| #include <math.h> |
|
|
|
|
| |
| |
| |
| |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) |
|
|
| #include "edge-impulse-sdk/CMSIS/DSP/Include/arm_helium_utils.h" |
| #include "edge-impulse-sdk/CMSIS/DSP/Include/arm_vec_math.h" |
|
|
| float32_t arm_logsumexp_f32(const float32_t *in, uint32_t blockSize) |
| { |
| float32_t maxVal; |
| const float32_t *pIn; |
| int32_t blkCnt; |
| float32_t accum=0.0f; |
| float32_t tmp; |
|
|
|
|
| arm_max_no_idx_f32((float32_t *) in, blockSize, &maxVal); |
|
|
|
|
| blkCnt = blockSize; |
| pIn = in; |
|
|
|
|
| f32x4_t vSum = vdupq_n_f32(0.0f); |
| blkCnt = blockSize >> 2; |
| while(blkCnt > 0) |
| { |
| f32x4_t vecIn = vld1q(pIn); |
| f32x4_t vecExp; |
|
|
| vecExp = vexpq_f32(vsubq_n_f32(vecIn, maxVal)); |
|
|
| vSum = vaddq_f32(vSum, vecExp); |
|
|
| |
| |
| |
| |
| pIn += 4; |
| blkCnt --; |
| } |
|
|
| |
| accum = vecAddAcrossF32Mve(vSum); |
|
|
| blkCnt = blockSize & 0x3; |
| while(blkCnt > 0) |
| { |
| tmp = *pIn++; |
| accum += expf(tmp - maxVal); |
| blkCnt--; |
| |
| } |
|
|
| accum = maxVal + logf(accum); |
|
|
| return (accum); |
| } |
|
|
| #else |
| #if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE) |
|
|
| #include "NEMath.h" |
| float32_t arm_logsumexp_f32(const float32_t *in, uint32_t blockSize) |
| { |
| float32_t maxVal; |
| float32_t tmp; |
| float32x4_t tmpV, tmpVb; |
| float32x4_t maxValV; |
| uint32x4_t idxV; |
| float32x4_t accumV; |
| float32x2_t accumV2; |
|
|
| const float32_t *pIn; |
| uint32_t blkCnt; |
| float32_t accum; |
| |
| pIn = in; |
|
|
| blkCnt = blockSize; |
|
|
| if (blockSize <= 3) |
| { |
| maxVal = *pIn++; |
| blkCnt--; |
|
|
| while(blkCnt > 0) |
| { |
| tmp = *pIn++; |
| |
| if (tmp > maxVal) |
| { |
| maxVal = tmp; |
| } |
| blkCnt--; |
| } |
| } |
| else |
| { |
| maxValV = vld1q_f32(pIn); |
| pIn += 4; |
| blkCnt = (blockSize - 4) >> 2; |
|
|
| while(blkCnt > 0) |
| { |
| tmpVb = vld1q_f32(pIn); |
| pIn += 4; |
| |
| idxV = vcgtq_f32(tmpVb, maxValV); |
| maxValV = vbslq_f32(idxV, tmpVb, maxValV ); |
|
|
| blkCnt--; |
| } |
|
|
| accumV2 = vpmax_f32(vget_low_f32(maxValV),vget_high_f32(maxValV)); |
| accumV2 = vpmax_f32(accumV2,accumV2); |
| maxVal = vget_lane_f32(accumV2, 0) ; |
|
|
| blkCnt = (blockSize - 4) & 3; |
|
|
| while(blkCnt > 0) |
| { |
| tmp = *pIn++; |
| |
| if (tmp > maxVal) |
| { |
| maxVal = tmp; |
| } |
| blkCnt--; |
| } |
|
|
| } |
|
|
| |
|
|
| maxValV = vdupq_n_f32(maxVal); |
| pIn = in; |
| accum = 0; |
| accumV = vdupq_n_f32(0.0f); |
|
|
| blkCnt = blockSize >> 2; |
|
|
| while(blkCnt > 0) |
| { |
| tmpV = vld1q_f32(pIn); |
| pIn += 4; |
| tmpV = vsubq_f32(tmpV, maxValV); |
| tmpV = vexpq_f32(tmpV); |
| accumV = vaddq_f32(accumV, tmpV); |
|
|
| blkCnt--; |
| |
| } |
| accumV2 = vpadd_f32(vget_low_f32(accumV),vget_high_f32(accumV)); |
| accum = vget_lane_f32(accumV2, 0) + vget_lane_f32(accumV2, 1); |
|
|
| blkCnt = blockSize & 0x3; |
| while(blkCnt > 0) |
| { |
| tmp = *pIn++; |
| accum += expf(tmp - maxVal); |
| blkCnt--; |
| |
| } |
|
|
| accum = maxVal + logf(accum); |
|
|
| return(accum); |
| } |
| #else |
| float32_t arm_logsumexp_f32(const float32_t *in, uint32_t blockSize) |
| { |
| float32_t maxVal; |
| float32_t tmp; |
| const float32_t *pIn; |
| uint32_t blkCnt; |
| float32_t accum; |
| |
| pIn = in; |
| blkCnt = blockSize; |
|
|
| maxVal = *pIn++; |
| blkCnt--; |
|
|
| while(blkCnt > 0) |
| { |
| tmp = *pIn++; |
|
|
| if (tmp > maxVal) |
| { |
| maxVal = tmp; |
| } |
| blkCnt--; |
| |
| } |
|
|
| blkCnt = blockSize; |
| pIn = in; |
| accum = 0; |
| while(blkCnt > 0) |
| { |
| tmp = *pIn++; |
| accum += expf(tmp - maxVal); |
| blkCnt--; |
| |
| } |
| accum = maxVal + logf(accum); |
|
|
| return(accum); |
| } |
| #endif |
| #endif |
|
|
| |
| |
| |
|
|
| #endif |
|
|