2014-05-19 4 views
0

Возможно ли запустить файл MEX параллельно с помощью Parallel Computing Toolbox в Matlab (parfor)? Я скомпилировал приложение Fortran в MEX-файл, используя gfortran-компилятор. Он работает без проблем:Параллельные вычисления с файлами MEX в Matlab?

mass=getMass(x); 

Но когда я пытаюсь запустить его параллельно, он падает. Fe .:

matlabpool 4 
parfor i=1:80 
    mass(i)=getMass(x); 
end 

Я получаю следующее сообщение об ошибке:

Error using distcomp.remoteparfor/getCompleteIntervals (line 22) The session that parfor is using has shut down.

Caused by: Error using distcomp.remoteparfor/getCompleteIntervals (line 22) The session that parfor is using has shut down.

The client lost connection to lab 3. This might be due to network problems, or the interactive matlabpool job might have errored.

Другие функции (не MEX) выполняются без проблем параллельно. Я использую Matlab R2013a на OS X 10.8.5.

+0

Как выглядит код для getMass? Он не может быть потокобезопасным. См., Например, https://software.intel.com/en-us/forums/topic/270572 –

+0

Это довольно сложная программа Fortran. Может быть, проблема с IO? Поскольку каждый раз он записывает на жесткий диск некоторые неформатированные данные: OPEN (UNIT = 3, FORM = "UNFORMATTED", ACCESS = "SEQUENTIAL") – picusiaubas

+0

Это может быть что угодно. IO или сохраненные переменные, кто знает. Попробуйте выполнить некоторую отладку. Попробуйте объявить подпрограмму 'recursive'. –

ответ

0

Ваша функция mex должна быть потокобезопасной. Если его части не являются потокобезопасными, например, Операций ввода-вывода в один файл, записи в общую память и т. Д., То эти части должны быть защищены мьютексом.

1

Вы можете легко использовать новый номер устройства для каждого open. Не забудьте также не писать в один и тот же файл из большего количества потоков, но из того, что вы представили, кажется, что у вас есть только скретч-файлы, и они должны быть в порядке, они отличаются номером устройства.

Если ваш компилятор поддерживает newunit спецификатор с Fortran 2008 это очень легко:

integer :: u 
open(newunit=u, form=... 

write(u,fmt) the_variables 

close(u) 

Он автоматически присваивает номер блока, который не используется и не в столкновении с каким-либо проводным номером устройства, потому что это отрицательный.

Также можно написать функцию, которая находит какой-либо свободный блок, используя inquire, но вы не должны вызывать такую ​​функцию из большего количества потоков одновременно.

subroutine newunit(unit) 
    integer,intent(out) :: unit 
    logical :: isOpen 

    integer, parameter :: MIN_UNIT_NUMBER = 10 
    integer, parameter :: MAX_UNIT_NUMBER = 99 

    do unit = MIN_UNIT_NUMBER, MAX_UNIT_NUMBER 
     inquire(unit = unit, opened = isOpen) 
     if (.not. isOpen) then 
      return 
     end if 
    end do 

    unit = -1 
    end subroutine newunit 

Более продвинутые версии существуют.

Смежные вопросы