使用OpenMP和MEX

时间:2015-08-03 13:34:47

标签: matlab openmp mex

我正在尝试计算3x3矩阵逆并将其乘以其他3x3矩阵。     这些计算的代码用作mex函数。     当我尝试使用OpenMP库时,我的问题开始了。     我试图制作矩阵逆并行的两个部分,并且我得到许多编译错误。     在评论pragma时,代码编译是干净的。     非常感谢您的帮助。

/*==========================================================
 * inv_and_mul_3by3.c
 * inverse 3x3 matrix and multiply it by another 3x3 matrix
 * The calling syntax is: outMatrix = (mat_to_inv,mat_to_mul)
 *========================================================*/

#include "mex.h"
#include <omp.h>

/* The computational routine */
void inv_and_mul_3by3_omp(double *mat_to_mul, double *mat_to_inv, double *out)
{
    // Description : out = inv(mat_to_inv)*mat_to_mul
    double det;
    double det_2by2;
    double det_2by2B;
    double inversed[9];

    // Calculating 2x2 determinant that is being calculated for the 3x3 determinant
    // and also for matrix inversion
    det_2by2  = mat_to_inv[4]*mat_to_inv[8] - mat_to_inv[7]*mat_to_inv[5];
    det_2by2B = mat_to_inv[1]*mat_to_inv[5] - mat_to_inv[4]*mat_to_inv[2];

    /* Calculate the matrix deteminant */
    det = mat_to_inv[0]*(det_2by2) - mat_to_inv[3]*(mat_to_inv[1]*mat_to_inv[8]-mat_to_inv[7]*mat_to_inv[2])+mat_to_inv[6]*(det_2by2B);

        #pragma omp parallel sections
        {

        #pragma omp section {
            // Calcualte the inversed matrix
            inversed[0] = (det_2by2)/det;
            inversed[3] = (mat_to_inv[6]*mat_to_inv[5] - mat_to_inv[3]*mat_to_inv[8])/det;
            inversed[6] = (mat_to_inv[3]*mat_to_inv[7] - mat_to_inv[6]*mat_to_inv[4])/det;
            inversed[1] = (mat_to_inv[7]*mat_to_inv[2] - mat_to_inv[1]*mat_to_inv[8])/det;
        }

       #pragma omp section {
            inversed[4] = (mat_to_inv[0]*mat_to_inv[8] - mat_to_inv[6]*mat_to_inv[2])/det;
            inversed[7] = (mat_to_inv[6]*mat_to_inv[1] - mat_to_inv[0]*mat_to_inv[7])/det;
            inversed[2] = (det_2by2B)/det;
            inversed[5] = (mat_to_inv[3]*mat_to_inv[2] - mat_to_inv[0]*mat_to_inv[5])/det;
            inversed[8] = (mat_to_inv[0]*mat_to_inv[4] - mat_to_inv[3]*mat_to_inv[1])/det;
        }
   } /*-- End of sections block --*/


    // multiply the matrix by the the matrix that was inversed
    out[0] = mat_to_mul[0]*inversed[0] + mat_to_mul[3]*inversed[1] + mat_to_mul[6]*inversed[2];
    out[1] = mat_to_mul[1]*inversed[0] + mat_to_mul[4]*inversed[1] + mat_to_mul[7]*inversed[2];
    out[2] = mat_to_mul[2]*inversed[0] + mat_to_mul[5]*inversed[1] + mat_to_mul[8]*inversed[2];
    out[3] = mat_to_mul[0]*inversed[3] + mat_to_mul[3]*inversed[4] + mat_to_mul[6]*inversed[5];
    out[4] = mat_to_mul[1]*inversed[3] + mat_to_mul[4]*inversed[4] + mat_to_mul[7]*inversed[5];
    out[5] = mat_to_mul[2]*inversed[3] + mat_to_mul[5]*inversed[4] + mat_to_mul[8]*inversed[5];
    out[6] = mat_to_mul[0]*inversed[6] + mat_to_mul[3]*inversed[7] + mat_to_mul[6]*inversed[8];
    out[7] = mat_to_mul[1]*inversed[6] + mat_to_mul[4]*inversed[7] + mat_to_mul[7]*inversed[8];
    out[8] = mat_to_mul[2]*inversed[6] + mat_to_mul[5]*inversed[7] + mat_to_mul[8]*inversed[8];

} //end function

/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
        int nrhs, const mxArray *prhs[])
{
    double *inMatToInv;             /* 3x3 input matrix that is inversed */
    double *inMatToMul;             /* 3x3 input matrix that multiply the inversed matrix*/
    double *outMatrix;              /* 3x3 output matrix */

    /* create pointers to the real data in the input matrix  */
    inMatToInv = mxGetPr(prhs[0]);
    inMatToMul = mxGetPr(prhs[1]);

    /* create the output matrix */
    plhs[0] = mxCreateDoubleMatrix(3,3,mxREAL);

    /* get a pointer to the real data in the output matrix */
    outMatrix = mxGetPr(plhs[0]);

    /* call the computational routine */
    inv_and_mul_3by3_omp(inMatToInv,inMatToMul,outMatrix);
}

这是我在Matlab中使用的编译命令 mex inv_and_mul_3by3_omp.c COMPFLAGS =&#34; / openmp $ COMPFLAGS&#34;

以下是编译错误: 使用mex时出错 inv_and_mul_3by3_omp.c (32):错误C3005:&#39; {&#39; :在OpenMP上遇到意外的令牌 &#39;部分&#39;指示
(35):错误C3047:OpenMP&#39;部分中的结构化块&#39; 区域必须在&#39; #pragma omp section&#39;之前。
(36):错误C3047:OpenMP&#39;部分中的结构化块&#39; 区域必须在&#39; #pragma omp section&#39;
之前 (37):错误C3047:OpenMP&#39;部分中的结构化块&#39; 区域必须在&#39; #pragma omp section&#39;
之前 (40):错误C3005:&#39; {&#39; :在OpenMP上遇到意外的令牌 &#39;部分&#39;指示
(40):错误C3044:&#39;部分&#39; :只允许直接嵌套 在OpenMP&#39;部分&#39;指示
(47):错误C2059:语法错误:&#39;}&#39;
(53):错误C2065:&#39; mat_to_mul&#39; :未声明的标识符
(53):错误C2109:下标需要数组或指针类型
(53):错误C2065:&#39;反转&#39; :未声明的标识符
(54):错误C2369:&#39; out&#39; :重新定义;不同的下标
        (53):见声明&#39; out&#39;
(54):错误C2065:&#39; mat_to_mul&#39; :未声明的标识符
(54):错误C2109:下标需要数组或指针类型
(54):错误C2065:&#39;反转&#39; :未声明的标识符
(55):错误C2369:&#39; out&#39; :重新定义;不同的下标
        (53):见声明&#39; out&#39;
(55):错误C2065:&#39; mat_to_mul&#39; :未声明的标识符
(55):错误C2109:下标需要数组或指针类型
(55):错误C2065:&#39;反转&#39; :未声明的标识符
(56):错误C2369:&#39; out&#39; :重新定义;不同的下标
        (53):见声明&#39; out&#39;
(56):错误C2065:&#39; mat_to_mul&#39; :未声明的标识符
(56):错误C2109:下标需要数组或指针类型
(56):错误C2065:&#39;反转&#39; :未声明的标识符
(57):错误C2369:&#39; out&#39; :重新定义;不同的下标
(53):见声明&#39; out&#39;
(57):错误C2065:&#39; mat_to_mul&#39; :未声明的标识符
(57):错误C2109:下标需要数组或指针类型
(57):错误C2065:&#39;反转&#39; :未声明的标识符
(58):错误C2369:&#39; out&#39; :重新定义;不同的下标
        (53):见声明&#39; out&#39; (58):错误C2065:&#39; mat_to_mul&#39; :未声明的标识符
(58):错误C2109:下标需要数组或指针类型
(58):错误C2065:&#39;反转&#39; :未声明的标识符
(59):错误C2369:&#39; out&#39; :重新定义;不同的下标
        (53):见声明&#39; out&#39; (59):错误C2065:&#39; mat_to_mul&#39; :未声明的标识符
(59):错误C2109:下标需要数组或指针类型
(59):错误C2065:&#39;反转&#39; :未声明的标识符
(60):错误C2369:&#39; out&#39; :重新定义;不同的下标
        (53):见声明&#39; out&#39; (60):错误C2065:&#39; mat_to_mul&#39; :未声明的标识符
(60):错误C2109:下标需要数组或指针类型
(60):错误C2065:&#39;反转&#39; :未声明的标识符
(62):错误C2059:语法错误:&#39;}&#39;

2 个答案:

答案 0 :(得分:1)

我要做的第一件事是删除嵌套的并行性。它并不像许多初学者认为的那样有用,如果没有设置编译器和/或环境变量,它就不一定可用,并且当你应该采取措施时,它正在向前推进。

替换此

#pragma omp parallel
{
    #pragma omp parallel sections num_threads(2)

#pragma omp parallel sections 

并相应地调整其余代码。为了补充我上面写的内容,尝试指定要使用的线程数通常是个坏主意,将其留给运行时系统来解决。

我并不假装这是一个完整的答案,而是一个简化代码的步骤,可以帮助说明错误的位置。

答案 1 :(得分:1)

尝试替换此

#pragma omp section {

通过这个

#pragma omp section 
{