- Main Page
- Modules
- Data Structures
- Files
- Examples

- File List
- Globals

# arm_mat_mult_fast_q31.c

Go to the documentation of this file.

    00001 /* ----------------------------------------------------------------------
    00002 * Copyright (C) 2010 ARM Limited. All rights reserved.
    00003 *
    00004 * $Date:        15. July 2011
    00005 * $Revision:    V1.0.10
    00006 *
    00007 * Project:      CMSIS DSP Library
    00008 * Title:        arm_mat_mult_fast_q31.c
    00009 *
    00010 * Description:   Q31 matrix multiplication (fast variant).
    00011 *
    00012 * Target Processor: Cortex-M4/Cortex-M3
    00013 *
    00014 * Version 1.0.10 2011/7/15
    00015 *    Big Endian support added and Merged M0 and M3/M4 Source code.
    00016 *
    00017 * Version 1.0.3 2010/11/29
    00018 *    Re-organized the CMSIS folders and updated documentation.
    00019 *
    00020 * Version 1.0.2 2010/11/11
    00021 *    Documentation updated.
    00022 *
    00023 * Version 1.0.1 2010/10/05
    00024 *    Production release and review comments incorporated.
    00025 *
    00026 * Version 1.0.0 2010/09/20
    00027 *    Production release and review comments incorporated.
    00028 * -------------------------------------------------------------------- */
    00029
    00030 #include "arm_math.h"
    00031
    00072 arm_status arm_mat_mult_fast_q31(
    00073   const arm_matrix_instance_q31 * pSrcA,
    00074   const arm_matrix_instance_q31 * pSrcB,
    00075   arm_matrix_instance_q31 * pDst)
    00076 {
    00077   q31_t *pIn1 = pSrcA->pData;                    /* input data matrix pointer A */
    00078   q31_t *pIn2 = pSrcB->pData;                    /* input data matrix pointer B */
    00079   q31_t *pInA = pSrcA->pData;                    /* input data matrix pointer A */
    00080 //  q31_t *pSrcB = pSrcB->pData;                    /* input data matrix pointer B */
    00081   q31_t *pOut = pDst->pData;                     /* output data matrix pointer */
    00082   q31_t *px;                                     /* Temporary output data matrix pointer */
    00083   q31_t sum;                                     /* Accumulator */
    00084   uint16_t numRowsA = pSrcA->numRows;            /* number of rows of input matrix A    */
    00085   uint16_t numColsB = pSrcB->numCols;            /* number of columns of input matrix B */
    00086   uint16_t numColsA = pSrcA->numCols;            /* number of columns of input matrix A */
    00087   uint16_t col, i = 0u, j, row = numRowsA, colCnt;      /* loop counters */
    00088   arm_status status;                             /* status of matrix multiplication */
    00089
    00090
    00091 #ifdef ARM_MATH_MATRIX_CHECK
    00092
    00093
    00094   /* Check for matrix mismatch condition */
    00095   if((pSrcA->numCols != pSrcB->numRows) ||
    00096      (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
    00097   {
    00098     /* Set status as ARM_MATH_SIZE_MISMATCH */
    00099     status = ARM_MATH_SIZE_MISMATCH;
    00100   }
    00101   else
    00102 #endif /*      #ifdef ARM_MATH_MATRIX_CHECK    */
    00103
    00104   {
    00105     /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
    00106     /* row loop */
    00107     do
    00108     {
    00109       /* Output pointer is set to starting address of the row being processed */
    00110       px = pOut + i;
    00111
    00112       /* For every row wise process, the column loop counter is to be initiated */
    00113       col = numColsB;
    00114
    00115       /* For every row wise process, the pIn2 pointer is set
    00116        ** to the starting address of the pSrcB data */
    00117       pIn2 = pSrcB->pData;
    00118
    00119       j = 0u;
    00120
    00121       /* column loop */
    00122       do
    00123       {
    00124         /* Set the variable sum, that acts as accumulator, to zero */
    00125         sum = 0;
    00126
    00127         /* Initiate the pointer pIn1 to point to the starting address of pInA */
    00128         pIn1 = pInA;
    00129
    00130         /* Apply loop unrolling and compute 4 MACs simultaneously. */
    00131         colCnt = numColsA >> 2;
    00132
    00133
    00134         /* matrix multiplication */
    00135         while(colCnt > 0u)
    00136         {
    00137           /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
    00138           /* Perform the multiply-accumulates */
    00139           sum = (q31_t) ((((q63_t) sum << 32) +
    00140                           ((q63_t) * pIn1++ * (*pIn2))) >> 32);
    00141           pIn2 += numColsB;
    00142           sum = (q31_t) ((((q63_t) sum << 32) +
    00143                           ((q63_t) * pIn1++ * (*pIn2))) >> 32);
    00144           pIn2 += numColsB;
    00145           sum = (q31_t) ((((q63_t) sum << 32) +
    00146                           ((q63_t) * pIn1++ * (*pIn2))) >> 32);
    00147           pIn2 += numColsB;
    00148           sum = (q31_t) ((((q63_t) sum << 32) +
    00149                           ((q63_t) * pIn1++ * (*pIn2))) >> 32);
    00150           pIn2 += numColsB;
    00151
    00152           /* Decrement the loop counter */
    00153           colCnt--;
    00154         }
    00155
    00156         /* If the columns of pSrcA is not a multiple of 4, compute any remaining output samples here.
    00157          ** No loop unrolling is used. */
    00158         colCnt = numColsA % 0x4u;
    00159
    00160         while(colCnt > 0u)
    00161         {
    00162           /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
    00163           /* Perform the multiply-accumulates */
    00164           sum = (q31_t) ((((q63_t) sum << 32) +
    00165                           ((q63_t) * pIn1++ * (*pIn2))) >> 32);
    00166           pIn2 += numColsB;
    00167
    00168           /* Decrement the loop counter */
    00169           colCnt--;
    00170         }
    00171
    00172         /* Convert the result from 2.30 to 1.31 format and store in destination buffer */
    00173         *px++ = sum << 1;
    00174
    00175         /* Update the pointer pIn2 to point to the  starting address of the next column */
    00176         j++;
    00177         pIn2 = pSrcB->pData + j;
    00178
    00179         /* Decrement the column loop counter */
    00180         col--;
    00181
    00182       } while(col > 0u);
    00183
    00184       /* Update the pointer pInA to point to the  starting address of the next row */
    00185       i = i + numColsB;
    00186       pInA = pInA + numColsA;
    00187
    00188       /* Decrement the row loop counter */
    00189       row--;
    00190
    00191     } while(row > 0u);
    00192
    00193     /* set status as ARM_MATH_SUCCESS */
    00194     status = ARM_MATH_SUCCESS;
    00195   }
    00196   /* Return to application */
    00197   return (status);
    00198 }
    00199

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines