| #include "edge-impulse-sdk/dsp/config.hpp" |
| #if EIDSP_LOAD_CMSIS_DSP_SOURCES |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include "edge-impulse-sdk/CMSIS/DSP/Include/dsp/matrix_functions.h" |
|
|
| #if defined(ARM_MATH_NEON) |
| #define GROUPOFROWS 8 |
| #endif |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| |
| |
| |
| |
|
|
|
|
|
|
| #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) |
|
|
| #define MATRIX_DIM3 3 |
| #define MATRIX_DIM4 4 |
|
|
| __STATIC_INLINE arm_status arm_mat_mult_f32_2x2_mve( |
| const arm_matrix_instance_f32 *pSrcA, |
| const arm_matrix_instance_f32 *pSrcB, |
| arm_matrix_instance_f32 *pDst) |
| { |
| |
| static const uint32_t offsetA0[4] = { 0, 0, 2, 2 }; |
| |
| static const uint32_t offsetB0[4] = { 0, 1, 0, 1 }; |
| |
| static const uint32_t offsetA1[4] = { 1, 1, 3, 3 }; |
| |
| static const uint32_t offsetB1[4] = { 2, 3, 2, 3 }; |
|
|
| uint32x4_t vecOffsA, vecOffsB; |
| f32x4_t vecInA, vecInB, vecDst; |
|
|
| vecOffsA = vldrwq_u32((uint32_t const *) offsetA0); |
| vecOffsB = vldrwq_u32((uint32_t const *) offsetB0); |
|
|
| vecInA = vldrwq_gather_shifted_offset((float32_t const *) pSrcA->pData, vecOffsA); |
| vecInB = vldrwq_gather_shifted_offset((float32_t const *) pSrcB->pData, vecOffsB); |
|
|
| vecDst = vmulq(vecInA, vecInB); |
|
|
| vecOffsA = vldrwq_u32((uint32_t const *) offsetA1); |
| vecOffsB = vldrwq_u32((uint32_t const *) offsetB1); |
|
|
| vecInA = vldrwq_gather_shifted_offset((float32_t const *) pSrcA->pData, vecOffsA); |
| vecInB = vldrwq_gather_shifted_offset((float32_t const *) pSrcB->pData, vecOffsB); |
|
|
| vecDst = vfmaq(vecDst, vecInA, vecInB); |
|
|
| vstrwq_f32(pDst->pData, vecDst); |
|
|
| return (ARM_MATH_SUCCESS); |
|
|
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| __STATIC_INLINE arm_status arm_mat_mult_f32_3x3_mve( |
| const arm_matrix_instance_f32 *pSrcA, |
| const arm_matrix_instance_f32 *pSrcB, |
| arm_matrix_instance_f32 *pDst) |
| { |
| float32_t *pInB = pSrcB->pData; |
| float32_t *pInA = pSrcA->pData; |
| float32_t *pOut = pDst->pData; |
| float32_t *pInA0, *pInA1, *pInA2; |
| f32x4_t vecMac0, vecMac1, vecMac2; |
| f32x4_t vecInB; |
| float32_t const *pSrBVec; |
|
|
| pSrBVec = (float32_t const *) pInB; |
|
|
| pInA0 = pInA; |
| pInA1 = pInA0 + MATRIX_DIM3; |
| pInA2 = pInA1 + MATRIX_DIM3; |
| |
| mve_pred16_t p0 = vctp32q(MATRIX_DIM3); |
|
|
| |
| |
| |
| vecInB = vldrwq_z_f32(pSrBVec, p0); |
| pSrBVec += MATRIX_DIM3; |
|
|
| vecMac0 = vmulq(vecInB, *pInA0++); |
| vecMac1 = vmulq(vecInB, *pInA1++); |
| vecMac2 = vmulq(vecInB, *pInA2++); |
| |
| |
| |
| vecInB = vldrwq_z_f32(pSrBVec, p0); |
| pSrBVec += MATRIX_DIM3; |
|
|
| vecMac0 = vfmaq(vecMac0, vecInB, *pInA0++); |
| vecMac1 = vfmaq(vecMac1, vecInB, *pInA1++); |
| vecMac2 = vfmaq(vecMac2, vecInB, *pInA2++); |
| |
| |
| |
| vecInB = vldrwq_z_f32(pSrBVec, p0); |
| pSrBVec += MATRIX_DIM3; |
|
|
| vecMac0 = vfmaq(vecMac0, vecInB, *pInA0++); |
| vecMac1 = vfmaq(vecMac1, vecInB, *pInA1++); |
| vecMac2 = vfmaq(vecMac2, vecInB, *pInA2++); |
|
|
| |
| vstrwq_p_f32(pOut, vecMac0, p0); |
| pOut += MATRIX_DIM3; |
| vstrwq_p_f32(pOut, vecMac1, p0); |
| pOut += MATRIX_DIM3; |
| vstrwq_p_f32(pOut, vecMac2, p0); |
| |
| |
| |
| return (ARM_MATH_SUCCESS); |
| } |
|
|
|
|
|
|
|
|
| __STATIC_INLINE arm_status arm_mat_mult_f32_4x4_mve( |
| const arm_matrix_instance_f32 *pSrcA, |
| const arm_matrix_instance_f32 *pSrcB, |
| arm_matrix_instance_f32 *pDst) |
| { |
| float32_t const *pSrBVec; |
| float32_t *pInB = pSrcB->pData; |
| float32_t *pInA = pSrcA->pData; |
| float32_t *pOut = pDst->pData; |
| float32_t *pInA0, *pInA1, *pInA2, *pInA3; |
| f32x4_t vecMac0, vecMac1, vecMac2, vecMac3; |
| f32x4_t vecInB; |
|
|
| pSrBVec = (float32_t const *) pInB; |
|
|
| pInA0 = pInA; |
| pInA1 = pInA0 + MATRIX_DIM4; |
| pInA2 = pInA1 + MATRIX_DIM4; |
| pInA3 = pInA2 + MATRIX_DIM4; |
| |
| |
| |
| vecInB = vld1q(pSrBVec); |
| pSrBVec += MATRIX_DIM4; |
|
|
| vecMac0 = vmulq(vecInB, *pInA0++); |
| vecMac1 = vmulq(vecInB, *pInA1++); |
| vecMac2 = vmulq(vecInB, *pInA2++); |
| vecMac3 = vmulq(vecInB, *pInA3++); |
| |
| |
| |
| vecInB = vld1q(pSrBVec); |
| pSrBVec += MATRIX_DIM4; |
|
|
| vecMac0 = vfmaq(vecMac0, vecInB, *pInA0++); |
| vecMac1 = vfmaq(vecMac1, vecInB, *pInA1++); |
| vecMac2 = vfmaq(vecMac2, vecInB, *pInA2++); |
| vecMac3 = vfmaq(vecMac3, vecInB, *pInA3++); |
| |
| |
| |
| vecInB = vld1q(pSrBVec); |
| pSrBVec += MATRIX_DIM4; |
|
|
| vecMac0 = vfmaq(vecMac0, vecInB, *pInA0++); |
| vecMac1 = vfmaq(vecMac1, vecInB, *pInA1++); |
| vecMac2 = vfmaq(vecMac2, vecInB, *pInA2++); |
| vecMac3 = vfmaq(vecMac3, vecInB, *pInA3++); |
| |
| |
| |
| vecInB = vld1q(pSrBVec); |
| pSrBVec += MATRIX_DIM4; |
|
|
| vecMac0 = vfmaq(vecMac0, vecInB, *pInA0++); |
| vecMac1 = vfmaq(vecMac1, vecInB, *pInA1++); |
| vecMac2 = vfmaq(vecMac2, vecInB, *pInA2++); |
| vecMac3 = vfmaq(vecMac3, vecInB, *pInA3++); |
|
|
| vst1q(pOut, vecMac0); |
| pOut += MATRIX_DIM4; |
| vst1q(pOut, vecMac1); |
| pOut += MATRIX_DIM4; |
| vst1q(pOut, vecMac2); |
| pOut += MATRIX_DIM4; |
| vst1q(pOut, vecMac3); |
| |
| |
| |
| return (ARM_MATH_SUCCESS); |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| arm_status arm_mat_mult_f32( |
| const arm_matrix_instance_f32 * pSrcA, |
| const arm_matrix_instance_f32 * pSrcB, |
| arm_matrix_instance_f32 * pDst) |
| { |
| float32_t *pInB = pSrcB->pData; |
| float32_t *pInA = pSrcA->pData; |
| float32_t *pOut = pDst->pData; |
| int numRowsA = pSrcA->numRows; |
| int numColsB = pSrcB->numCols; |
| int numColsA = pSrcA->numCols; |
| uint32_t blkCnt; |
| uint32_t i; |
| arm_status status; |
|
|
| #ifdef ARM_MATH_MATRIX_CHECK |
|
|
| |
| if ((pSrcA->numCols != pSrcB->numRows) || |
| (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols)) |
| { |
| |
| status = ARM_MATH_SIZE_MISMATCH; |
| } |
| else |
| #endif |
| { |
| |
| if(numRowsA == numColsB && numColsB == numColsA) { |
| if (numRowsA == 1) |
| { |
| pOut[0] = pInA[0] * pInB[0]; |
| return(ARM_MATH_SUCCESS); |
| } |
| else if(numRowsA == 2) |
| return arm_mat_mult_f32_2x2_mve(pSrcA, pSrcB, pDst); |
| else if(numRowsA == 3) |
| return arm_mat_mult_f32_3x3_mve(pSrcA, pSrcB, pDst); |
| else if(numRowsA == 4) |
| return arm_mat_mult_f32_4x4_mve(pSrcA, pSrcB, pDst); |
| } |
|
|
| |
| i = numRowsA >> 2; |
| while (i > 0U) |
| { |
| float32_t *pInA0, *pInA1, *pInA2, *pInA3; |
| float32_t *pInB0; |
| float32_t *pOut0, *pOut1, *pOut2, *pOut3; |
| f32x4_t vecMac0, vecMac1, vecMac2, vecMac3; |
| f32x4_t vecInB; |
|
|
| |
| pOut0 = pOut; |
| pOut1 = pOut0 + numColsB; |
| pOut2 = pOut1 + numColsB; |
| pOut3 = pOut2 + numColsB; |
| pInB0 = pInB; |
|
|
| uint32_t k = numColsB >> 2; |
| while (k > 0U) |
| { |
| |
| pInA0 = pInA; |
| pInA1 = pInA0 + numColsA; |
| pInA2 = pInA1 + numColsA; |
| pInA3 = pInA2 + numColsA; |
|
|
| vecMac0 = vdupq_n_f32(0.0f); |
| vecMac1 = vdupq_n_f32(0.0f); |
| vecMac2 = vdupq_n_f32(0.0f); |
| vecMac3 = vdupq_n_f32(0.0f); |
|
|
| blkCnt = numColsA; |
|
|
| while (blkCnt > 0U) |
| { |
| |
| |
| |
| vecInB = *(f32x4_t *)pInB0; |
|
|
| vecMac0 = vfmaq(vecMac0, vecInB, *pInA0++); |
| vecMac1 = vfmaq(vecMac1, vecInB, *pInA1++); |
| vecMac2 = vfmaq(vecMac2, vecInB, *pInA2++); |
| vecMac3 = vfmaq(vecMac3, vecInB, *pInA3++); |
|
|
| pInB0 = pInB0 + numColsB; |
| |
| |
| |
| blkCnt--; |
| } |
|
|
| |
| vst1q(pOut0, vecMac0); |
| pOut0 += 4; |
| vst1q(pOut1, vecMac1); |
| pOut1 += 4; |
| vst1q(pOut2, vecMac2); |
| pOut2 += 4; |
| vst1q(pOut3, vecMac3); |
| pOut3 += 4; |
|
|
| |
| |
| |
| pInB0 -= (numColsB * numColsA) - 4; |
| k--; |
| } |
|
|
| int colBLeft = numColsB & 3; |
| if (colBLeft) |
| { |
| pInA0 = pInA; |
| pInA1 = pInA0 + numColsA; |
| pInA2 = pInA1 + numColsA; |
| pInA3 = pInA2 + numColsA; |
| mve_pred16_t p0 = vctp32q(colBLeft); |
|
|
| vecMac0 = vdupq_n_f32(0.0f); |
| vecMac1 = vdupq_n_f32(0.0f); |
| vecMac2 = vdupq_n_f32(0.0f); |
| vecMac3 = vdupq_n_f32(0.0f); |
|
|
| blkCnt = numColsA; |
|
|
| while (blkCnt > 0U) |
| { |
| |
| |
| |
| vecInB = vldrwq_z_f32(pInB0, p0); |
|
|
| vecMac0 = vfmaq(vecMac0, vecInB, *pInA0++); |
| vecMac1 = vfmaq(vecMac1, vecInB, *pInA1++); |
| vecMac2 = vfmaq(vecMac2, vecInB, *pInA2++); |
| vecMac3 = vfmaq(vecMac3, vecInB, *pInA3++); |
|
|
| pInB0 = pInB0 + numColsB; |
| |
| |
| |
| blkCnt--; |
| } |
|
|
| |
| vstrwq_p_f32(pOut0, vecMac0, p0); |
| vstrwq_p_f32(pOut1, vecMac1, p0); |
| vstrwq_p_f32(pOut2, vecMac2, p0); |
| vstrwq_p_f32(pOut3, vecMac3, p0); |
| } |
|
|
| |
| pInA += 4 * numColsA; |
| pOut += 4 * numColsB; |
| i--; |
| } |
|
|
| |
| |
| |
| |
| if (numRowsA & 3) |
| { |
| i = numRowsA & 3; |
| while (i > 0U) |
| { |
| float32_t *pInA0; |
| float32_t *pInB0; |
| float32_t *pOut0; |
| f32x4_t vecInB; |
| f32x4_t vecMac0; |
|
|
| pOut0 = pOut; |
| pInB0 = pInB; |
|
|
| uint32_t k = numColsB >> 2; |
| while (k > 0U) |
| { |
| pInA0 = pInA; |
|
|
| vecMac0 = vdupq_n_f32(0.0f); |
| blkCnt = numColsA; |
| while (blkCnt > 0U) |
| { |
| |
| |
| |
| vecInB = *(f32x4_t *)pInB0; |
|
|
| vecMac0 = vfmaq(vecMac0, vecInB, *pInA0++); |
|
|
| pInB0 = pInB0 + numColsB; |
| |
| |
| |
| blkCnt--; |
| } |
|
|
| |
| vst1q(pOut0, vecMac0); |
| pOut0 += 4; |
|
|
| |
| |
| |
| pInB0 -= (numColsB * numColsA) - 4; |
| k--; |
| } |
|
|
| int colBLeft = numColsB & 3; |
| if (colBLeft) |
| { |
| pInA0 = pInA; |
| mve_pred16_t p0 = vctp32q(colBLeft); |
|
|
| vecMac0 = vdupq_n_f32(0.0f); |
| blkCnt = numColsA; |
| while (blkCnt > 0U) |
| { |
| |
| |
| |
| vecInB = vldrwq_z_f32(pInB0, p0); |
|
|
| vecMac0 = vfmaq(vecMac0, vecInB, *pInA0++); |
|
|
| pInB0 = pInB0 + numColsB; |
| |
| |
| |
| blkCnt--; |
| } |
| |
| vstrwq_p_f32(pOut0, vecMac0, p0); |
| } |
|
|
| |
| pInA += 1 * numColsA; |
| pOut += 1 * numColsB; |
| i--; |
| } |
| |
| } |
| status = ARM_MATH_SUCCESS; |
| } |
|
|
| |
| return (status); |
| } |
| #else |
|
|
| #if defined(ARM_MATH_NEON) |
| |
| |
| |
| |
| |
| |
| |
| |
| arm_status arm_mat_mult_f32( |
| const arm_matrix_instance_f32 * pSrcA, |
| const arm_matrix_instance_f32 * pSrcB, |
| arm_matrix_instance_f32 * pDst) |
| { |
| float32_t *pIn1 = pSrcA->pData; |
| float32_t *pIn2 = pSrcB->pData; |
| float32_t *pInA = pSrcA->pData; |
| float32_t *pOut = pDst->pData; |
| float32_t *px; |
| float32_t sum; |
| uint16_t numRowsA = pSrcA->numRows; |
| uint16_t numColsB = pSrcB->numCols; |
| uint16_t numColsA = pSrcA->numCols; |
|
|
|
|
| uint16_t col, i = 0U, j, row = numRowsA, rowCnt, colCnt; |
| arm_status status; |
|
|
| float32x4_t a0V, a1V, a2V, a3V, a4V, a5V, a6V, a7V; |
| float32x4_t acc0,acc1,acc2,acc3,acc4,acc5,acc6,acc7,temp; |
| float32x2_t accum = vdup_n_f32(0); |
| float32_t *pIn1B = pSrcA->pData; |
| float32_t *pIn1C = pSrcA->pData; |
| float32_t *pIn1D = pSrcA->pData; |
| float32_t *pIn1E = pSrcA->pData; |
| float32_t *pIn1F = pSrcA->pData; |
| float32_t *pIn1G = pSrcA->pData; |
| float32_t *pIn1H = pSrcA->pData; |
|
|
| float32_t *pxB,*pxC, *pxD, *pxE, *pxF, *pxG, *pxH; |
| float32_t sum0,sum1, sum2,sum3, sum4, sum5 , sum6, sum7; |
|
|
| #ifdef ARM_MATH_MATRIX_CHECK |
|
|
| |
| if ((pSrcA->numCols != pSrcB->numRows) || |
| (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols)) |
| { |
| |
| status = ARM_MATH_SIZE_MISMATCH; |
| } |
| else |
| #endif |
| { |
| |
| |
| rowCnt = row >> 3; |
|
|
| while(rowCnt > 0) |
| { |
| |
| px = pOut + GROUPOFROWS*i; |
| pxB = px + numColsB; |
| pxC = px + 2*numColsB; |
| pxD = px + 3*numColsB; |
| pxE = px + 4*numColsB; |
| pxF = px + 5*numColsB; |
| pxG = px + 6*numColsB; |
| pxH = px + 7*numColsB; |
|
|
| |
| col = numColsB; |
|
|
| |
| |
| pIn2 = pSrcB->pData; |
|
|
| j = 0U; |
|
|
| |
| do |
| { |
| |
| sum0 = 0.0f; |
| sum1 = 0.0f; |
| sum2 = 0.0f; |
| sum3 = 0.0f; |
| sum4 = 0.0f; |
| sum5 = 0.0f; |
| sum6 = 0.0f; |
| sum7 = 0.0f; |
|
|
| |
| pIn1 = pInA; |
| pIn1B = pIn1 + numColsA; |
| pIn1C = pIn1 + 2*numColsA; |
| pIn1D = pIn1 + 3*numColsA; |
| pIn1E = pIn1 + 4*numColsA; |
| pIn1F = pIn1 + 5*numColsA; |
| pIn1G = pIn1 + 6*numColsA; |
| pIn1H = pIn1 + 7*numColsA; |
|
|
| acc0 = vdupq_n_f32(0.0); |
| acc1 = vdupq_n_f32(0.0); |
| acc2 = vdupq_n_f32(0.0); |
| acc3 = vdupq_n_f32(0.0); |
| acc4 = vdupq_n_f32(0.0); |
| acc5 = vdupq_n_f32(0.0); |
| acc6 = vdupq_n_f32(0.0); |
| acc7 = vdupq_n_f32(0.0); |
|
|
| |
| colCnt = numColsA >> 2U; |
|
|
| |
| while (colCnt > 0U) |
| { |
| |
| a0V = vld1q_f32(pIn1); |
| a1V = vld1q_f32(pIn1B); |
| a2V = vld1q_f32(pIn1C); |
| a3V = vld1q_f32(pIn1D); |
| a4V = vld1q_f32(pIn1E); |
| a5V = vld1q_f32(pIn1F); |
| a6V = vld1q_f32(pIn1G); |
| a7V = vld1q_f32(pIn1H); |
|
|
| pIn1 += 4; |
| pIn1B += 4; |
| pIn1C += 4; |
| pIn1D += 4; |
| pIn1E += 4; |
| pIn1F += 4; |
| pIn1G += 4; |
| pIn1H += 4; |
| |
| temp = vsetq_lane_f32(*pIn2,temp,0); |
| pIn2 += numColsB; |
| temp = vsetq_lane_f32(*pIn2,temp,1); |
| pIn2 += numColsB; |
| temp = vsetq_lane_f32(*pIn2,temp,2); |
| pIn2 += numColsB; |
| temp = vsetq_lane_f32(*pIn2,temp,3); |
| pIn2 += numColsB; |
|
|
| acc0 = vmlaq_f32(acc0,a0V,temp); |
| acc1 = vmlaq_f32(acc1,a1V,temp); |
| acc2 = vmlaq_f32(acc2,a2V,temp); |
| acc3 = vmlaq_f32(acc3,a3V,temp); |
| acc4 = vmlaq_f32(acc4,a4V,temp); |
| acc5 = vmlaq_f32(acc5,a5V,temp); |
| acc6 = vmlaq_f32(acc6,a6V,temp); |
| acc7 = vmlaq_f32(acc7,a7V,temp); |
|
|
| |
| colCnt--; |
| } |
|
|
| accum = vpadd_f32(vget_low_f32(acc0), vget_high_f32(acc0)); |
| sum0 += vget_lane_f32(accum, 0) + vget_lane_f32(accum, 1); |
|
|
| accum = vpadd_f32(vget_low_f32(acc1), vget_high_f32(acc1)); |
| sum1 += vget_lane_f32(accum, 0) + vget_lane_f32(accum, 1); |
|
|
| accum = vpadd_f32(vget_low_f32(acc2), vget_high_f32(acc2)); |
| sum2 += vget_lane_f32(accum, 0) + vget_lane_f32(accum, 1); |
|
|
| accum = vpadd_f32(vget_low_f32(acc3), vget_high_f32(acc3)); |
| sum3 += vget_lane_f32(accum, 0) + vget_lane_f32(accum, 1); |
|
|
| accum = vpadd_f32(vget_low_f32(acc4), vget_high_f32(acc4)); |
| sum4 += vget_lane_f32(accum, 0) + vget_lane_f32(accum, 1); |
|
|
| accum = vpadd_f32(vget_low_f32(acc5), vget_high_f32(acc5)); |
| sum5 += vget_lane_f32(accum, 0) + vget_lane_f32(accum, 1); |
|
|
| accum = vpadd_f32(vget_low_f32(acc6), vget_high_f32(acc6)); |
| sum6 += vget_lane_f32(accum, 0) + vget_lane_f32(accum, 1); |
|
|
| accum = vpadd_f32(vget_low_f32(acc7), vget_high_f32(acc7)); |
| sum7 += vget_lane_f32(accum, 0) + vget_lane_f32(accum, 1); |
|
|
| |
| |
| colCnt = numColsA & 3; |
|
|
| while (colCnt > 0U) |
| { |
| |
| sum0 += *pIn1++ * (*pIn2); |
| sum1 += *pIn1B++ * (*pIn2); |
| sum2 += *pIn1C++ * (*pIn2); |
| sum3 += *pIn1D++ * (*pIn2); |
| sum4 += *pIn1E++ * (*pIn2); |
| sum5 += *pIn1F++ * (*pIn2); |
| sum6 += *pIn1G++ * (*pIn2); |
| sum7 += *pIn1H++ * (*pIn2); |
| pIn2 += numColsB; |
|
|
| |
| colCnt--; |
| } |
|
|
| |
| *px++ = sum0; |
| *pxB++ = sum1; |
| *pxC++ = sum2; |
| *pxD++ = sum3; |
| *pxE++ = sum4; |
| *pxF++ = sum5; |
| *pxG++ = sum6; |
| *pxH++ = sum7; |
|
|
| |
| j++; |
| pIn2 = pSrcB->pData + j; |
|
|
| |
| col--; |
|
|
| } while (col > 0U); |
|
|
| |
| i = i + numColsB; |
| pInA = pInA + GROUPOFROWS*numColsA; |
|
|
| |
| rowCnt--; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| i = GROUPOFROWS*i; |
| rowCnt = row & 7; |
|
|
| while(rowCnt > 0) |
| { |
| |
| px = pOut + i; |
|
|
| |
| col = numColsB; |
|
|
| |
| |
| pIn2 = pSrcB->pData; |
|
|
| j = 0U; |
|
|
| |
| do |
| { |
| |
| sum = 0.0f; |
|
|
| |
| pIn1 = pInA; |
|
|
| acc0 = vdupq_n_f32(0.0); |
|
|
| |
| colCnt = numColsA >> 2U; |
|
|
| |
| while (colCnt > 0U) |
| { |
| |
| a0V = vld1q_f32(pIn1); |
| pIn1 += 4; |
| |
| temp = vsetq_lane_f32(*pIn2,temp,0); |
| pIn2 += numColsB; |
| temp = vsetq_lane_f32(*pIn2,temp,1); |
| pIn2 += numColsB; |
| temp = vsetq_lane_f32(*pIn2,temp,2); |
| pIn2 += numColsB; |
| temp = vsetq_lane_f32(*pIn2,temp,3); |
| pIn2 += numColsB; |
|
|
| acc0 = vmlaq_f32(acc0,a0V,temp); |
|
|
| |
| colCnt--; |
| } |
|
|
| accum = vpadd_f32(vget_low_f32(acc0), vget_high_f32(acc0)); |
| sum += vget_lane_f32(accum, 0) + vget_lane_f32(accum, 1); |
|
|
| |
| |
| colCnt = numColsA % 0x4U; |
|
|
| while (colCnt > 0U) |
| { |
| |
| sum += *pIn1++ * (*pIn2); |
| pIn2 += numColsB; |
|
|
| |
| colCnt--; |
| } |
|
|
| |
| *px++ = sum; |
|
|
| |
| j++; |
| pIn2 = pSrcB->pData + j; |
|
|
| |
| col--; |
|
|
| } while (col > 0U); |
|
|
|
|
| |
| i = i + numColsB; |
| pInA = pInA + numColsA; |
|
|
| |
| rowCnt--; |
|
|
| } |
| |
| status = ARM_MATH_SUCCESS; |
| } |
|
|
| |
| return (status); |
| } |
| #else |
| |
| |
| |
| |
| |
| |
| |
| |
| arm_status arm_mat_mult_f32( |
| const arm_matrix_instance_f32 * pSrcA, |
| const arm_matrix_instance_f32 * pSrcB, |
| arm_matrix_instance_f32 * pDst) |
| { |
| float32_t *pIn1 = pSrcA->pData; |
| float32_t *pIn2 = pSrcB->pData; |
| float32_t *pInA = pSrcA->pData; |
| float32_t *pInB = pSrcB->pData; |
| float32_t *pOut = pDst->pData; |
| float32_t *px; |
| float32_t sum; |
| uint16_t numRowsA = pSrcA->numRows; |
| uint16_t numColsB = pSrcB->numCols; |
| uint16_t numColsA = pSrcA->numCols; |
| uint32_t col, i = 0U, row = numRowsA, colCnt; |
| arm_status status; |
|
|
| #ifdef ARM_MATH_MATRIX_CHECK |
|
|
| |
| if ((pSrcA->numCols != pSrcB->numRows) || |
| (pSrcA->numRows != pDst->numRows) || |
| (pSrcB->numCols != pDst->numCols) ) |
| { |
| |
| status = ARM_MATH_SIZE_MISMATCH; |
| } |
| else |
|
|
| #endif |
|
|
| { |
| |
| |
| do |
| { |
| |
| px = pOut + i; |
|
|
| |
| col = numColsB; |
|
|
| |
| pIn2 = pSrcB->pData; |
|
|
| |
| do |
| { |
| |
| sum = 0.0f; |
|
|
| |
| pIn1 = pInA; |
|
|
| #if defined (ARM_MATH_LOOPUNROLL) |
|
|
| |
| colCnt = numColsA >> 2U; |
|
|
| |
| while (colCnt > 0U) |
| { |
| |
|
|
| |
| sum += *pIn1++ * *pIn2; |
| pIn2 += numColsB; |
|
|
| sum += *pIn1++ * *pIn2; |
| pIn2 += numColsB; |
|
|
| sum += *pIn1++ * *pIn2; |
| pIn2 += numColsB; |
|
|
| sum += *pIn1++ * *pIn2; |
| pIn2 += numColsB; |
|
|
| |
| colCnt--; |
| } |
|
|
| |
| colCnt = numColsA % 0x4U; |
|
|
| #else |
|
|
| |
| colCnt = numColsA; |
|
|
| #endif |
|
|
| while (colCnt > 0U) |
| { |
| |
|
|
| |
| sum += *pIn1++ * *pIn2; |
| pIn2 += numColsB; |
|
|
| |
| colCnt--; |
| } |
|
|
| |
| *px++ = sum; |
|
|
| |
| col--; |
|
|
| |
| pIn2 = pInB + (numColsB - col); |
|
|
| } while (col > 0U); |
|
|
| |
| i = i + numColsB; |
| pInA = pInA + numColsA; |
|
|
| |
| row--; |
|
|
| } while (row > 0U); |
|
|
| |
| status = ARM_MATH_SUCCESS; |
| } |
|
|
| |
| return (status); |
| } |
|
|
| #endif |
| #endif |
|
|
| |
| |
| |
|
|
| #endif |
|
|