Запустите параллельно n-функции, которые совместно используют некоторую переменную - PullRequest
1 голос
/ 08 октября 2019

Я пытался запустить этот простой код, но он не работает, я не могу передать вывод func1 в func2 для дальнейших вычислений. Очевидно, func1 и func2 являются лишь примером, чтобы лучше понять, что я буду делать.

parfor i = 1:2
    if i == 1
      a = func1();
    else
      func2(a);
    end
end

 function a = func1()
     a = 3;
 end
 function o = func2(x)
    o = x + 2;   
 end

При выполнении этого я получаю следующую ошибку:

An UndefinedFunction error was thrown on the workers for 'a'.  This might be because the file containing
'a' is not accessible on the workers.  Use addAttachedFiles(pool, files) to specify the required files
to be attached.  For more information see the documentation for 'parallel.Pool/addAttachedFiles'.

Caused by:
    Undefined function or variable 'a'.

Как передать выход func1 в цикл parfor?

1 Ответ

2 голосов
/ 11 октября 2019

Проблема в том, что parfor выполняет цикл по своей природе в случайном порядке, чтобы заставить вас сделать все вычисления независимыми от других. Ваш код зависит . Вы не можете запустить i=2 до i=1, потому что значение a не установлено в этом случае (что более или менее говорит длинная и сложная ошибка). Вы должны сделать каждую итерацию цикла независимой от всех остальных, чтобы иметь возможность распараллелить ее.

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

parfor ii=1:5
    disp(ii)
end

Это может привести, например, к 4 3 5 2 1 или любой другой перестановке. Это происходит потому, что каждое ядро ​​получает одну итераций и выдает результат, как только это будет сделано.

Таким образом, для вашего "простого" примера решение будет следующим:1019 * сначала вычислить a=func1(), а затем выполнить parfor ii = 2:2.

В общем: рекурсивные циклы (т. Е. Цикл, в котором любая итерация зависит от результата предыдущей, но очень далекой) нельзя распараллелить. Таким образом, напишите свой код, чтобы он не был рекурсивным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...