Как использовать M-файл в цикле parfor в Matlab?

мой код внутри цикла parfor становится все длиннее и длиннее, и я хотел бы разделить его. Сохранение частей кода в разных файлах сценариев кажется логичным и очень привлекательным, и, поскольку это ничего не меняет, кроме места сохранения кода, кажется, что это должно работать. Но это не так.

Я получаю обычное сообщение "Ошибка нарушения прозрачности".

Проблема кажется типичной, но я нигде не нашел этот вопрос или ответ на него.

Ниже приведен небольшой рабочий пример.

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

C = NaN(10,1); %Result vector
parfor loop = 1:10
    a = 1;
    b = 2;

    MFile_Test %Run the m-file which contains only one line:
    % c = a + b;

    C(loop)=c;

end

MFile_Test — это скрипт, содержащий только строку one line c = a + b.

Я начинаю понимать, почему параллельные вычисления имеют здесь проблему, но не то, как ее решить. Поскольку это было бы возможно без каких-либо проблем, если бы у меня была строка c = a + b внутри файла parfor, я не могу поверить, что нет простого способа решить эту проблему (например, в худшем случае что-то вроде сказать Matlab загрузить текст из другого файл и запустить его как код здесь и сейчас).

Если есть альтернативные способы структурировать мой код без использования файлов скриптов (и, если возможно, без использования одних только функций ;)) Буду признателен и за такие комментарии, конечно.

Большое спасибо, Даниэль


person Dan    schedule 14.05.2015    source источник
comment
Кстати, я также экспериментировал с addAttachedFiles(gcp,{'mydata'}) или с использованием сохранения('mydata'), а затем загрузки('mydata') внутри скрипта, но ни один из них не работал.   -  person Dan    schedule 14.05.2015
comment
Я не знаю другого способа, кроме функций. parfor потребуется ссылка на каждую используемую переменную. Если вы вызываете скрипт, эта ссылка теряется. Короче говоря, ваш сценарий больше не прозрачен. См. это и это. Если ваша проблема в том, что код становится уродливым из-за количества входных и выходных переменных, вы можете использовать structures или cells.   -  person Autonomous    schedule 14.05.2015
comment
В качестве хакерской альтернативы передаче всех переменных в функцию вы можете сохранить рабочую область в вызывающем скрипте и снова загрузить ее внутри функции.   -  person Cecilia    schedule 14.05.2015
comment
Почему вы избегаете функций? Скрипты MATLAB отлично подходят для прототипирования, особенно скрипты режима ячеек, но их не следует использовать для структурного программирования. Я настоятельно рекомендую функции.   -  person Tony    schedule 14.05.2015
comment
Спасибо за комментарии. Я только начал использовать ячейки в этом отношении, Параг, но чувствую, что это делает мой код менее понятным. Но ладно, буду пользоваться дальше. Вариант сохранения и перезагрузки рабочего пространства кажется мне удобным, я рассмотрю его, спасибо, Сесилия.   -  person Dan    schedule 14.05.2015


Ответы (2)


parfor имеет различные ограничения, из-за которых использование скриптов внутри цикла, как правило, является плохим вариантом. Основное ограничение состоит в том, что текст цикла parfor должен поддаваться анализу, чтобы увидеть, какие новые переменные могут быть созданы — это называется "прозрачность" в документе. Вместо этого попробуйте использовать функцию.

person Edric    schedule 14.05.2015
comment
Хорошо, тогда мне придется. Все еще не понимаю, почему текст скрипта нельзя просто прочитать из Matlab, равный тексту в основном файле, но я думаю, что это я. Поэтому я отмечу ответ как правильный, чтобы закрыть вопрос. Спасибо вам всем. - person Dan; 14.05.2015

Итак, для других людей или возможных советов по улучшению, вот как я сделал это с функцией и загрузкой входных переменных.

a = 1;
b = 2;
save('Input.mat');

pseudo_input = NaN;%for the function

D= NaN(10,1);%result vector
parfor loop = 1:10
D(loop) = Parfor_Fun_Test(pseudo_input);
end

И функция выглядит так:

function d = Parfor_Fun_Test(InputArgs)
load('Input.mat');
d = a + b ;
end

Я бы предпочел также сохранить вывод, то есть «d», внутри функции, а затем загрузить его в цикле parfor, но это вызывает ошибку, вероятно, потому, что один и тот же файл одновременно загружается и сохраняется разными параллельные рабочие. Так что это придется сделать. (По-видимому, это можно обойти с помощью сохранение под другим именем каждый раз, но это, вероятно, сильно замедлит код.)

Кстати, кажется, что использование ячеек или структур немного быстрее, но тогда я должен написать код внутри функции, как я предполагаю:

d = Input.a + Input.b ;

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

person Dan    schedule 14.05.2015