Как использовать OpenMP в моем MEX-файле без сбоя MATLAB? - PullRequest
0 голосов
/ 21 сентября 2019

Я создал Windows MEX-файл из Visual Studio 2019. Моя версия MATLAB - R2019a.Код просто выполняет некоторую «сортировку» двух входных массивов matlab.Это пример, который я пытаюсь использовать с OpenMP."test.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;

Идеальным выводом будет ячейка 2 * 1 в result.Если я уберу строку # pragma, MEX-файл будет работать хорошо.Если я добавлю это, MATLAB потерпел крах.Я пытался найти проблему в течение нескольких дней и не нашел никакого решения.Кроме того,

  1. Я выбрал ключ поддержки OpenMP для "да" в моей Visual Studio.
  2. Я не использую mexPrintf в своем коде.Я слышал, что функция будет вызывать сбой MEX-файла с OpenMP.
  3. Я установил Intel Studio параллельно XE 2019 и обновил 5 Matlab R2019a.Возможно, я ошибся в определении параллельного домена.Я не хочу включать последнюю часть из plhs[0] = mxCreateCellMatrix(2, 1); в параллельную часть #pragma.Как коды выше, я делаю это правильно?

Ответы [ 2 ]

1 голос
/ 24 сентября 2019

Возможно, это не идеальное решение.Я только что исправил коды и преуспел в создании mexw64 внутри Matlab.Что касается компиляции кода в visual studio, то мексранс очень низкий. (VS построил 15 с, а Matlab построил 0,4 с, я не мог понять, почему.) Сначала я исправил две критические ошибки.

  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-файла.Я просто предлагаю не собирать и не применять мекс в одном файле.Мой Matlab иногда ломался.Я не знаю причину.Мне просто удалось отделить их, даже звучит очень странно.

1 голос
/ 21 сентября 2019

Вы не можете вызывать любые функции mx... или mex... в параллельной части вашего кода *.Вы должны получить указатели на все данные перед параллельным разделом, включая создание выходных массивов и получение их указателей, а затем выполнять только ваши вычисления параллельно.


* Правило, данное здесь, слишком широкое, некоторыеmx... функции могут быть в порядке для использования в параллельной секции, как указано в комментарий Джеймса Турсы .Я предпочитаю не угадывать и соблюдать простые правила.

...