| #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_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE) |
| __STATIC_FORCEINLINE arm_status arm_mat_mult_q7_2x2_mve( |
| const arm_matrix_instance_q7 * pSrcA, |
| const arm_matrix_instance_q7 * pSrcB, |
| arm_matrix_instance_q7 * pDst) |
| { |
| const uint32_t MATRIX_DIM = 2; |
| q7_t const *pInB = (q7_t const *)pSrcB->pData; |
| q7_t *pInA = pSrcA->pData; |
| q7_t *pOut = pDst->pData; |
| uint8x16_t vecColBOffs; |
| q7_t *pInA0 = pInA; |
| q7_t *pInA1 = pInA0 + MATRIX_DIM; |
| q31_t acc0, acc1; |
| q7x16_t vecB, vecA0, vecA1; |
| mve_pred16_t p0 = vctp8q(MATRIX_DIM); |
|
|
| vecColBOffs = vidupq_u8((uint32_t)0, 2); |
|
|
| pInB = pSrcB->pData; |
|
|
| vecB = vldrbq_gather_offset_z(pInB, vecColBOffs, p0); |
|
|
| vecA0 = vldrbq_s8(pInA0); |
| vecA1 = vldrbq_s8(pInA1); |
|
|
| acc0 = vmladavq_s8(vecA0, vecB); |
| acc1 = vmladavq_s8(vecA1, vecB); |
|
|
| pOut[0 * MATRIX_DIM] = (q7_t) __SSAT(acc0 >> 7, 8); |
| pOut[1 * MATRIX_DIM] = (q7_t) __SSAT(acc1 >> 7, 8); |
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrbq_gather_offset_z(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmladavq_s8(vecA0, vecB); |
| acc1 = vmladavq_s8(vecA1, vecB); |
|
|
| pOut[0 * MATRIX_DIM] = (q7_t) __SSAT(acc0 >> 7, 8); |
| pOut[1 * MATRIX_DIM] = (q7_t) __SSAT(acc1 >> 7, 8); |
| |
| |
| |
| return (ARM_MATH_SUCCESS); |
| } |
|
|
|
|
| __STATIC_FORCEINLINE arm_status arm_mat_mult_q7_3x3_mve( |
| const arm_matrix_instance_q7 * pSrcA, |
| const arm_matrix_instance_q7 * pSrcB, |
| arm_matrix_instance_q7 * pDst) |
| { |
| const uint8_t MATRIX_DIM = 3; |
| q7_t const *pInB = (q7_t const *)pSrcB->pData; |
| q7_t *pInA = pSrcA->pData; |
| q7_t *pOut = pDst->pData; |
| uint8x16_t vecColBOffs; |
| q7_t *pInA0 = pInA; |
| q7_t *pInA1 = pInA0 + MATRIX_DIM; |
| q7_t *pInA2 = pInA1 + MATRIX_DIM; |
| q31_t acc0, acc1, acc2; |
| q7x16_t vecB, vecA0, vecA1, vecA2; |
| mve_pred16_t p0 = vctp8q(MATRIX_DIM); |
|
|
| vecColBOffs = vidupq_u8((uint32_t)0, 1); |
| vecColBOffs = vecColBOffs * MATRIX_DIM; |
|
|
| pInB = pSrcB->pData; |
|
|
| vecB = vldrbq_gather_offset_z(pInB, vecColBOffs, p0); |
|
|
| vecA0 = vldrbq_s8(pInA0); |
| vecA1 = vldrbq_s8(pInA1); |
| vecA2 = vldrbq_s8(pInA2); |
|
|
| acc0 = vmladavq_s8(vecA0, vecB); |
| acc1 = vmladavq_s8(vecA1, vecB); |
| acc2 = vmladavq_s8(vecA2, vecB); |
|
|
| pOut[0 * MATRIX_DIM] = (q7_t) __SSAT(acc0 >> 7, 8); |
| pOut[1 * MATRIX_DIM] = (q7_t) __SSAT(acc1 >> 7, 8); |
| pOut[2 * MATRIX_DIM] = (q7_t) __SSAT(acc2 >> 7, 8); |
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrbq_gather_offset_z(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmladavq_s8(vecA0, vecB); |
| acc1 = vmladavq_s8(vecA1, vecB); |
| acc2 = vmladavq_s8(vecA2, vecB); |
|
|
| pOut[0 * MATRIX_DIM] = (q7_t) __SSAT(acc0 >> 7, 8); |
| pOut[1 * MATRIX_DIM] = (q7_t) __SSAT(acc1 >> 7, 8); |
| pOut[2 * MATRIX_DIM] = (q7_t) __SSAT(acc2 >> 7, 8); |
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrbq_gather_offset_z(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmladavq_s8(vecA0, vecB); |
| acc1 = vmladavq_s8(vecA1, vecB); |
| acc2 = vmladavq_s8(vecA2, vecB); |
|
|
| pOut[0 * MATRIX_DIM] = (q7_t) __SSAT(acc0 >> 7, 8); |
| pOut[1 * MATRIX_DIM] = (q7_t) __SSAT(acc1 >> 7, 8); |
| pOut[2 * MATRIX_DIM] = (q7_t) __SSAT(acc2 >> 7, 8); |
| |
| |
| |
| return (ARM_MATH_SUCCESS); |
| } |
|
|
|
|
| __STATIC_FORCEINLINE arm_status arm_mat_mult_q7_4x4_mve( |
| const arm_matrix_instance_q7 * pSrcA, |
| const arm_matrix_instance_q7 * pSrcB, |
| arm_matrix_instance_q7 * pDst) |
| { |
| const uint32_t MATRIX_DIM = 4; |
| q7_t const *pInB = (q7_t const *)pSrcB->pData; |
| q7_t *pInA = pSrcA->pData; |
| q7_t *pOut = pDst->pData; |
| uint8x16_t vecColBOffs; |
| q7_t *pInA0 = pInA; |
| q7_t *pInA1 = pInA0 + MATRIX_DIM; |
| q7_t *pInA2 = pInA1 + MATRIX_DIM; |
| q7_t *pInA3 = pInA2 + MATRIX_DIM; |
| q31_t acc0, acc1, acc2, acc3; |
| q7x16_t vecB, vecA0, vecA1, vecA2, vecA3; |
| mve_pred16_t p0 = vctp8q(MATRIX_DIM); |
|
|
| vecColBOffs = vidupq_u8((uint32_t)0, 4); |
|
|
| pInB = pSrcB->pData; |
|
|
| vecB = vldrbq_gather_offset_z(pInB, vecColBOffs, p0); |
|
|
| vecA0 = vldrbq_s8(pInA0); |
| vecA1 = vldrbq_s8(pInA1); |
| vecA2 = vldrbq_s8(pInA2); |
| vecA3 = vldrbq_s8(pInA3); |
|
|
| acc0 = vmladavq_s8(vecA0, vecB); |
| acc1 = vmladavq_s8(vecA1, vecB); |
| acc2 = vmladavq_s8(vecA2, vecB); |
| acc3 = vmladavq_s8(vecA3, vecB); |
|
|
| pOut[0 * MATRIX_DIM] = (q7_t) __SSAT(acc0 >> 7, 8); |
| pOut[1 * MATRIX_DIM] = (q7_t) __SSAT(acc1 >> 7, 8); |
| pOut[2 * MATRIX_DIM] = (q7_t) __SSAT(acc2 >> 7, 8); |
| pOut[3 * MATRIX_DIM] = (q7_t) __SSAT(acc3 >> 7, 8); |
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrbq_gather_offset_z(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmladavq_s8(vecA0, vecB); |
| acc1 = vmladavq_s8(vecA1, vecB); |
| acc2 = vmladavq_s8(vecA2, vecB); |
| acc3 = vmladavq_s8(vecA3, vecB); |
|
|
| pOut[0 * MATRIX_DIM] = (q7_t) __SSAT(acc0 >> 7, 8); |
| pOut[1 * MATRIX_DIM] = (q7_t) __SSAT(acc1 >> 7, 8); |
| pOut[2 * MATRIX_DIM] = (q7_t) __SSAT(acc2 >> 7, 8); |
| pOut[3 * MATRIX_DIM] = (q7_t) __SSAT(acc3 >> 7, 8); |
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrbq_gather_offset_z(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmladavq_s8(vecA0, vecB); |
| acc1 = vmladavq_s8(vecA1, vecB); |
| acc2 = vmladavq_s8(vecA2, vecB); |
| acc3 = vmladavq_s8(vecA3, vecB); |
|
|
| pOut[0 * MATRIX_DIM] = (q7_t) __SSAT(acc0 >> 7, 8); |
| pOut[1 * MATRIX_DIM] = (q7_t) __SSAT(acc1 >> 7, 8); |
| pOut[2 * MATRIX_DIM] = (q7_t) __SSAT(acc2 >> 7, 8); |
| pOut[3 * MATRIX_DIM] = (q7_t) __SSAT(acc3 >> 7, 8); |
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrbq_gather_offset_z(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmladavq_s8(vecA0, vecB); |
| acc1 = vmladavq_s8(vecA1, vecB); |
| acc2 = vmladavq_s8(vecA2, vecB); |
| acc3 = vmladavq_s8(vecA3, vecB); |
|
|
| pOut[0 * MATRIX_DIM] = (q7_t) __SSAT(acc0 >> 7, 8); |
| pOut[1 * MATRIX_DIM] = (q7_t) __SSAT(acc1 >> 7, 8); |
| pOut[2 * MATRIX_DIM] = (q7_t) __SSAT(acc2 >> 7, 8); |
| pOut[3 * MATRIX_DIM] = (q7_t) __SSAT(acc3 >> 7, 8); |
| |
| |
| |
| return (ARM_MATH_SUCCESS); |
| } |
|
|
| arm_status arm_mat_mult_q7( |
| const arm_matrix_instance_q7 * pSrcA, |
| const arm_matrix_instance_q7 * pSrcB, |
| arm_matrix_instance_q7 * pDst, |
| q7_t * pState) |
| { |
| q7_t *pInA = pSrcA->pData; |
| q7_t *pInB = pSrcB->pData; |
| q7_t *pInA2; |
| q7_t *pInB2; |
| q7_t *px; |
| q7_t *px2; |
| uint32_t numRowsA = pSrcA->numRows; |
| uint32_t numColsB = pSrcB->numCols; |
| uint32_t numColsA = pSrcA->numCols; |
| uint32_t numRowsB = pSrcB->numRows; |
| uint32_t col, i = 0u, j, row = numRowsB; |
| q7_t *pSrcBT = pState; |
| uint32_t blkCnt; |
| arm_status status; |
| arm_matrix_instance_q7 BT; |
|
|
|
|
| #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 == 2) |
| return arm_mat_mult_q7_2x2_mve(pSrcA, pSrcB, pDst); |
| else if(numRowsA == 3) |
| return arm_mat_mult_q7_3x3_mve(pSrcA, pSrcB, pDst); |
| else if (numRowsA == 4) |
| return arm_mat_mult_q7_4x4_mve(pSrcA, pSrcB, pDst); |
| } |
| |
| |
| |
|
|
| BT.numRows = numColsB; |
| BT.numCols = numRowsB; |
| BT.pData = pSrcBT; |
|
|
| arm_mat_trans_q7(pSrcB, &BT); |
|
|
| |
| |
| |
| i = 0; |
| row = numRowsA >> 1; |
| px = pDst->pData; |
| px2 = px + numColsB; |
|
|
| |
| |
| |
|
|
| |
| |
| |
| while (row > 0u) |
| { |
| |
| |
| |
| col = numColsB >> 1; |
| |
| |
| |
| |
| pInB = pSrcBT; |
| pInB2 = pInB + numRowsB; |
| j = 0; |
|
|
| |
| |
| |
| while (col > 0u) |
| { |
| q7_t const *pSrcAVec, *pSrcBVec, *pSrcA2Vec, *pSrcB2Vec; |
| q7x16_t vecA, vecA2, vecB, vecB2; |
| q31_t acc0, acc1, acc2, acc3; |
|
|
| |
| |
| |
| pInA = pSrcA->pData + i; |
| pInA2 = pInA + numColsA; |
| pInB = pSrcBT + j; |
| pInB2 = pInB + numRowsB; |
|
|
| pSrcAVec = (q7_t const *) pInA; |
| pSrcA2Vec = (q7_t const *)pInA2; |
| pSrcBVec = (q7_t const *) pInB; |
| pSrcB2Vec = (q7_t const *)pInB2; |
|
|
| acc0 = 0L; |
| acc1 = 0L; |
| acc2 = 0L; |
| acc3 = 0L; |
|
|
| vecA = vld1q(pSrcAVec); |
| pSrcAVec += 16; |
|
|
| blkCnt = numColsA >> 4; |
| while (blkCnt > 0U) |
| { |
| vecB = vld1q(pSrcBVec); |
| pSrcBVec += 16; |
| acc0 = vmladavaq_s8(acc0, vecA, vecB); |
| vecA2 = vld1q(pSrcA2Vec); |
| pSrcA2Vec += 16; |
| acc1 = vmladavaq_s8(acc1, vecA2, vecB); |
| vecB2 = vld1q(pSrcB2Vec); |
| pSrcB2Vec += 16; |
| acc2 = vmladavaq_s8(acc2, vecA, vecB2); |
| vecA = vld1q(pSrcAVec); |
| pSrcAVec += 16; |
| acc3 = vmladavaq_s8(acc3, vecA2, vecB2); |
|
|
| blkCnt--; |
| } |
| |
| |
| |
| |
| blkCnt = numColsA & 0xF; |
| if (blkCnt > 0U) |
| { |
| mve_pred16_t p0 = vctp8q(blkCnt); |
| vecB = vld1q(pSrcBVec); |
| acc0 = vmladavaq_p_s8(acc0, vecA, vecB, p0); |
| vecA2 = vld1q(pSrcA2Vec); |
| acc1 = vmladavaq_p_s8(acc1, vecA2, vecB, p0); |
| vecB2 = vld1q(pSrcB2Vec); |
| acc2 = vmladavaq_p_s8(acc2, vecA, vecB2, p0); |
| vecA = vld1q(pSrcAVec); |
| acc3 = vmladavaq_p_s8(acc3, vecA2, vecB2, p0); |
| } |
|
|
| *px++ = (q7_t) __SSAT(acc0 >> 7, 8); |
| *px++ = (q7_t) __SSAT(acc2 >> 7, 8); |
| *px2++ = (q7_t) __SSAT(acc1 >> 7, 8); |
| *px2++ = (q7_t) __SSAT(acc3 >> 7, 8); |
| j += numRowsB * 2; |
| |
| |
| |
| col--; |
|
|
| } |
|
|
| i = i + numColsA * 2; |
| px = px2 + (numColsB & 1u); |
| px2 = px + numColsB; |
| |
| |
| |
| row--; |
| } |
|
|
| |
| |
| |
|
|
| if (numColsB & 1u) |
| { |
| row = numRowsA & (~0x1); |
| px = pDst->pData + numColsB - 1; |
| i = 0; |
|
|
| |
| |
| |
| while (row > 0) |
| { |
| q7_t const *pSrcAVec, *pSrcBVec; |
| q7x16_t vecA, vecB; |
| q63_t acc0; |
|
|
| |
| |
| |
| pInB = pSrcBT + numRowsB * (numColsB - 1); |
| pInA = pSrcA->pData + i; |
|
|
| pSrcAVec = (q7_t const *) pInA; |
| pSrcBVec = (q7_t const *) pInB; |
|
|
| acc0 = 0LL; |
| blkCnt = (numColsA) >> 4; |
| while (blkCnt > 0U) |
| { |
| vecA = vld1q(pSrcAVec); |
| pSrcAVec += 16; |
| vecB = vld1q(pSrcBVec); |
| pSrcBVec += 16; |
| acc0 = vmladavaq_s8(acc0, vecA, vecB); |
|
|
| blkCnt--; |
| } |
| |
| |
| |
| |
| blkCnt = numColsA & 0xF; |
| if (blkCnt > 0U) |
| { |
| mve_pred16_t p0 = vctp8q(blkCnt); |
| vecA = vld1q(pSrcAVec); |
| vecB = vld1q(pSrcBVec); |
| acc0 = vmladavaq_p_s8(acc0, vecA, vecB, p0); |
| } |
|
|
| *px = (q7_t) __SSAT(acc0 >> 7, 8); |
|
|
| px += numColsB; |
|
|
| i += numColsA; |
| |
| |
| |
| row--; |
| } |
| } |
|
|
| if (numRowsA & 1u) |
| { |
| col = numColsB; |
| i = 0u; |
| |
| |
| |
| px = pDst->pData + (numColsB) * (numRowsA - 1); |
| |
| |
| |
| while (col > 0) |
| { |
| q7_t const *pSrcAVec, *pSrcBVec; |
| q7x16_t vecA, vecB; |
| q63_t acc0; |
|
|
| |
| |
| |
| pInA = pSrcA->pData + (numRowsA - 1) * numColsA; |
| pInB = pSrcBT + i; |
|
|
| |
| |
| |
| pSrcAVec = (q7_t const *) pInA; |
| pSrcBVec = (q7_t const *) pInB; |
| acc0 = 0LL; |
|
|
| blkCnt = (numColsA) >> 4; |
| while (blkCnt > 0U) |
| { |
| vecA = vld1q(pSrcAVec); |
| pSrcAVec += 16; |
| vecB = vld1q(pSrcBVec); |
| pSrcBVec += 16; |
| acc0 = vmladavaq_s8(acc0, vecA, vecB); |
|
|
| blkCnt--; |
| } |
| |
| |
| |
| |
| blkCnt = numColsA & 0xF; |
| if (blkCnt > 0U) |
| { |
| mve_pred16_t p0 = vctp8q(blkCnt); |
| vecA = vld1q(pSrcAVec); |
| vecB = vld1q(pSrcBVec); |
| acc0 = vmladavaq_p_s8(acc0, vecA, vecB, p0); |
| } |
|
|
| *px++ = (q7_t) __SSAT(acc0 >> 7, 8); |
|
|
| i += numColsA; |
|
|
| |
| |
| |
| col--; |
| } |
| } |
| |
| |
| |
| status = ARM_MATH_SUCCESS; |
| } |
| return(status); |
| } |
| #else |
| arm_status arm_mat_mult_q7(const arm_matrix_instance_q7 *pSrcA, const arm_matrix_instance_q7 *pSrcB, arm_matrix_instance_q7 *pDst, q7_t *pState) |
| { |
| q31_t sum; |
| q7_t *pIn1 = pSrcA->pData; |
| q7_t *pIn2 = pSrcB->pData; |
| q7_t *pInA = pSrcA->pData; |
| q7_t *pInB = pSrcB->pData; |
| q7_t *pOut = pDst->pData; |
| q7_t *px; |
| uint16_t numColsB = pSrcB->numCols; |
| uint16_t numColsA = pSrcA->numCols; |
| uint16_t numRowsA = pSrcA->numRows; |
| uint16_t col, i = 0U, row = numRowsA, colCnt; |
| arm_status status; |
|
|
| (void)pState; |
|
|
| #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; |
|
|
| |
| pIn1 = pInA; |
|
|
| |
| colCnt = numColsA; |
|
|
| |
| while (colCnt > 0U) { |
| |
| |
| sum += (q31_t)*pIn1++ * *pIn2; |
| pIn2 += numColsB; |
|
|
| |
| colCnt--; |
| } |
|
|
| |
| |
| *px++ = (q7_t)__SSAT((sum >> 7), 8); |
|
|
| |
| 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 |
|
|