繁体   English   中英

如何在我的 MEX 文件中使用 OpenMP 而不会导致 MATLAB 崩溃?

[英]How to use OpenMP in my MEX-file without crashing MATLAB?

我从 Visual Studio 2019 构建了一个 Windows MEX 文件。我的 MATLAB 版本是 R2019a。 该代码只是对两个输入 matlab 数组进行了一些“排序”。 这是我尝试与 OpenMP 一起使用的示例。 “测试.cpp”

#include "mex.h"
#include <vector>
#include <iostream>
#include <algorithm>
#include <omp.h>
using namespace std;
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{ 
    mxDouble *p0 = mxGetDoubles(prhs[0]);
    mwSize size0 = mxGetNumberOfElements(prhs[0]);
    mxDouble* p1 = mxGetDoubles(prhs[1]);
    mwSize size1 = mxGetNumberOfElements(prhs[1]);
    vector<vector<int>> v(2);
    int i;
    for (i = 0; i < size0; i++) {
        v[0].push_back(int(*p0++));
    };
    for (i = 0; i < size1; i++) {
        v[1].push_back(int(*p1++));
    };
#pragma omp parallel for 
    for (i = 0; i < 2; i++) {
        sort(v[i].begin(), v[i].end());
    };


    plhs[0] = mxCreateCellMatrix(2, 1);
    for (int i = 0; i < 2; i++) {
        mxArray* str = mxCreateNumericMatrix(1, v[i].size(), mxDOUBLE_CLASS, mxREAL);
        copy(v[i].begin(), v[i].end(), mxGetPr(str));
        mxSetCell(plhs[0], i, mxDuplicateArray(str));
        mxDestroyArray(str);
    };
    return;
}

我的测试 M 文件是:

a1= [1,2,3,4,5];
a2= [1,1,1,1];
result = test(a1,a2);
clear mex;

理想的 output result将是 2*1 单元格。 如果我删除# pragma行,则 MEX 文件运行良好。 如果我添加它,MATLAB 崩溃了。 几天来我一直试图找到问题并没有找到任何解决方案。 除了,

  1. 我已在 Visual Studio 中选择 OpenMP 支持键为“是”。
  2. 我不在我的代码中使用mexPrintf 我听说 function 会使用 OpenMP 使 MEX 文件崩溃。
  3. 我已经安装了 Intel Studio 并行 XE 2019 并更新了 Matlab R2019a 的 5。 也许我做了一个错误的并行域定义。 我不想包含plhs[0] = mxCreateCellMatrix(2, 1);的最后一部分进入#pragma并行部分。 如上面的代码,我做对了吗?

您不能在代码的并行部分调用任何mx...mex...函数*。 您必须在并行部分之前获取指向所有数据的指针,包括创建 output arrays 并获取它们的指针,然后仅并行执行计算。


* 这里给出的规则过于宽泛,一些mx...函数可能可以在并行部分中使用,如James Tursa 的评论所示。 我不喜欢猜测并保持规则简单。

这可能不是完美的解决方案。 我刚刚对代码进行了一些更正,并成功在 Matlab 中构建了 mexw64。 至于在visual studio中编译代码,mex跑得很低。(VS构建15s和Matlab构建0.4s我不知道为什么。)首先,我纠正了两个严重错误。

  1. 正确使用#pragma...的花括号。 左花括号不能直接在#pragma omp parallel之后。 它应该在一个新行中。 如下,
#pragma omp parallel
{ 
#pragma omp for
    for (i = 0; i < 2; i++) {
        sort(v[i].begin(), v[i].end());
    };
}

2.在并行循环中,不能使用mwIndex类型的索引。 它必须是int类型。 这些问题的代码中不会发生此错误。 我只是记下来。

然后我用mex -v COMPFLAGS="$COMPFLAGS /openmp" test.cpp; 构建 mex 文件。 我只是建议不要在一个 m 文件中构建和应用 mex。 我的 Matlab 有时会崩溃。 我不知道原因。 我刚刚成功地将它们分开,甚至听起来很奇怪。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM