将部分与 OpenMP 和 MEX 结合使用
Using sections with OpenMP and 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="/openmp $COMPFLAGS"
以下是编译错误:
使用 mex 时出错
inv_and_mul_3by3_omp.c
(32):错误 C3005:“{”:在 OpenMP 上遇到意外标记
'section' 指令
(35):错误 C3047:OpenMP 中的结构化块 'sections'
区域前面必须有“#pragma omp section”
(36):错误 C3047:OpenMP 中的结构化块 'sections'
区域前面必须有“#pragma omp section”
(37):错误 C3047:OpenMP 中的结构化块 'sections'
区域前面必须有“#pragma omp section”
(40):错误 C3005:“{”:在 OpenMP 上遇到意外标记
'section' 指令
(40) : error C3044: 'section' : 只允许直接嵌套
在 OpenMP 'sections' 指令下
(47):错误 C2059:语法错误:“}”
(53):错误 C2065:'mat_to_mul':未声明的标识符
(53) : error C2109: 下标需要数组或指针类型
(53):错误 C2065:'inversed':未声明的标识符
(54) : error C2369: 'out' : 重定义;不同的下标
(53) : 见 'out'
的声明
(54):错误 C2065:'mat_to_mul':未声明的标识符
(54) : error C2109: 下标需要数组或指针类型
(54):错误 C2065:'inversed':未声明的标识符
(55):错误 C2369:'out':重新定义;不同的下标
(53) : 见 'out'
的声明
(55):错误 C2065:'mat_to_mul':未声明的标识符
(55) : error C2109: 下标需要数组或指针类型
(55):错误 C2065:'inversed':未声明的标识符
(56):错误 C2369:'out':重新定义;不同的下标
(53) : 见 'out'
的声明
(56):错误 C2065:'mat_to_mul':未声明的标识符
(56) : error C2109: 下标需要数组或指针类型
(56):错误 C2065:'inversed':未声明的标识符
(57):错误 C2369:'out':重新定义;不同的下标
(53) : 见 'out'
的声明
(57):错误 C2065:'mat_to_mul':未声明的标识符
(57) : error C2109: 下标需要数组或指针类型
(57):错误 C2065:'inversed':未声明的标识符
(58):错误 C2369:'out':重新定义;不同的下标
(53) : 见 'out' 的声明
(58):错误 C2065:'mat_to_mul':未声明的标识符
(58) : error C2109: 下标需要数组或指针类型
(58):错误 C2065:'inversed':未声明的标识符
(59):错误 C2369:'out':重新定义;不同的下标
(53) : 见 'out' 的声明
(59):错误 C2065:'mat_to_mul':未声明的标识符
(59) : error C2109: 下标需要数组或指针类型
(59):错误 C2065:'inversed':未声明的标识符
(60) : error C2369: 'out' : 重定义;不同的下标
(53) : 见 'out' 的声明
(60):错误 C2065:'mat_to_mul':未声明的标识符
(60) : error C2109: 下标需要数组或指针类型
(60):错误 C2065:'inversed':未声明的标识符
(62):错误 C2059:语法错误:'}'
我要做的第一件事是去除嵌套并行性。它并不像许多初学者认为的那样有用,如果不设置编译器 and/or 环境变量,它不一定可用,并且当您应该采取一些小步骤时它正在向前推进。
替换此
#pragma omp parallel
{
#pragma omp parallel sections num_threads(2)
和
#pragma omp parallel sections
并相应地调整其余代码。补充一下我上面写的,尝试指定要使用的线程数通常不是一个好主意,将其留给运行时系统来确定。
我并不假装这是一个完整的答案,而是一个简化代码的步骤,可能有助于阐明错误所在。
尝试替换这个
#pragma omp section {
由此
#pragma omp section
{
我正在尝试计算 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="/openmp $COMPFLAGS"
以下是编译错误:
使用 mex 时出错
inv_and_mul_3by3_omp.c
(32):错误 C3005:“{”:在 OpenMP 上遇到意外标记
'section' 指令
(35):错误 C3047:OpenMP 中的结构化块 'sections'
区域前面必须有“#pragma omp section”
(36):错误 C3047:OpenMP 中的结构化块 'sections'
区域前面必须有“#pragma omp section”
(37):错误 C3047:OpenMP 中的结构化块 'sections'
区域前面必须有“#pragma omp section”
(40):错误 C3005:“{”:在 OpenMP 上遇到意外标记
'section' 指令
(40) : error C3044: 'section' : 只允许直接嵌套
在 OpenMP 'sections' 指令下
(47):错误 C2059:语法错误:“}”
(53):错误 C2065:'mat_to_mul':未声明的标识符
(53) : error C2109: 下标需要数组或指针类型
(53):错误 C2065:'inversed':未声明的标识符
(54) : error C2369: 'out' : 重定义;不同的下标
(53) : 见 'out'
的声明
(54):错误 C2065:'mat_to_mul':未声明的标识符
(54) : error C2109: 下标需要数组或指针类型
(54):错误 C2065:'inversed':未声明的标识符
(55):错误 C2369:'out':重新定义;不同的下标
(53) : 见 'out'
的声明
(55):错误 C2065:'mat_to_mul':未声明的标识符
(55) : error C2109: 下标需要数组或指针类型
(55):错误 C2065:'inversed':未声明的标识符
(56):错误 C2369:'out':重新定义;不同的下标
(53) : 见 'out'
的声明
(56):错误 C2065:'mat_to_mul':未声明的标识符
(56) : error C2109: 下标需要数组或指针类型
(56):错误 C2065:'inversed':未声明的标识符
(57):错误 C2369:'out':重新定义;不同的下标
(53) : 见 'out'
的声明
(57):错误 C2065:'mat_to_mul':未声明的标识符
(57) : error C2109: 下标需要数组或指针类型
(57):错误 C2065:'inversed':未声明的标识符
(58):错误 C2369:'out':重新定义;不同的下标
(53) : 见 'out' 的声明
(58):错误 C2065:'mat_to_mul':未声明的标识符
(58) : error C2109: 下标需要数组或指针类型
(58):错误 C2065:'inversed':未声明的标识符
(59):错误 C2369:'out':重新定义;不同的下标
(53) : 见 'out' 的声明
(59):错误 C2065:'mat_to_mul':未声明的标识符
(59) : error C2109: 下标需要数组或指针类型
(59):错误 C2065:'inversed':未声明的标识符
(60) : error C2369: 'out' : 重定义;不同的下标
(53) : 见 'out' 的声明
(60):错误 C2065:'mat_to_mul':未声明的标识符
(60) : error C2109: 下标需要数组或指针类型
(60):错误 C2065:'inversed':未声明的标识符
(62):错误 C2059:语法错误:'}'
我要做的第一件事是去除嵌套并行性。它并不像许多初学者认为的那样有用,如果不设置编译器 and/or 环境变量,它不一定可用,并且当您应该采取一些小步骤时它正在向前推进。
替换此
#pragma omp parallel
{
#pragma omp parallel sections num_threads(2)
和
#pragma omp parallel sections
并相应地调整其余代码。补充一下我上面写的,尝试指定要使用的线程数通常不是一个好主意,将其留给运行时系统来确定。
我并不假装这是一个完整的答案,而是一个简化代码的步骤,可能有助于阐明错误所在。
尝试替换这个
#pragma omp section {
由此
#pragma omp section
{