matlab, использующий evalin в parfor

#matlab #parfor

#matlab #parfor

Вопрос:

У меня проблема с использованием evalin внутри функции, которая вызывается в теле parfor-loop . Функция выглядит следующим образом:

 function returnData = extractFun(input)

    % assign close price to function call
    x = evalin('base','data');

    % extract prices
    returnData = x(input);

end
  

И скрипт, вызывающий функцию, выглядит следующим образом:

 % data-array = n-by-1 double
data = [1:1000]';

% loop and extract data
parfor i = 1:10

    % n-by-1 cell array containing 1-by-x doubles
    % doubles in var1 contain valid indicies for the data-variable

    var1 = {[1:10]; [1:30]};

    % perform cell-function since, cell2mat will not work due to
    % inconsistent dimensions of the double arrays contained in the cells

    extractData = cellfun(@returnData,var1,'UniformOutput',false);

    % do something with extractData

end
  

Когда я запускаю скрипт в parfor цикле, matlab выдает ошибку, что индекс превышает размеры матрицы, что должно означать, что переменная x пуста (или вычисляется неправильно). Странно то, что когда я запускаю цикл как обычный for цикл, все работает нормально. Я знаю о проблемах прозрачности с parfor циклами, поэтому я поместил evalin в отдельную функцию.

Я также был бы открыт для альтернативных решений моей проблемы, которая заключается в извлечении данных из одной переменной данных в массив размером n на 1 ячейку as doubles без использования дополнительных циклов, поскольку я намереваюсь выполнить этот цикл с очень большим количеством итераций.

Кто-нибудь может мне помочь? Спасибо!

Ответ №1:

evalin и parfor не смешивайте. Даже если вы работаете parfor с локальным пулом, вы хотите думать о рабочих, которые выполняют итерации цикла, как о совершенно отдельных процессах. Другими словами, у них вообще нет видимости вашего базового рабочего пространства. evalin не допускается в теле цикла по определенной причине; скрытие его в функции не меняет того факта, что в локальной базовой рабочей области worker нет переменной data , что приведет к сбою инструкции.

Мне непонятно, почему вы так боитесь цикла в этом контексте. Прежде всего, это уже не 2006 год, когда циклы все еще были довольно плохими для вас; была проделана некоторая работа по оптимизации Matlab. Во-вторых, ваш cellfun вызов с evalin — довольно неэффективный способ простого чтения индексов, и cellfun он делает не намного больше, чем скрывает цикл. В-третьих, вы планируете работать parfor здесь, что означает, что вы, возможно, не сможете справиться с вероятным увеличением использования памяти из-за замены полностью векторизованного цикла.

Следовательно, просто замените cellfun -call на

 extractData = cell(size(var));
for iVar = 1:numel(var)
    extractData{iVar} = data(var{iVar});
end
  

Комментарии:

1. Решили использовать это решение. Вы правы — дополнительное время обработки дополнительного цикла не так плохо, как я думал, и едва ли быстрее, чем cellfun (скорее всего, как вы сказали, потому что это на самом деле своего рода цикл в конце концов). Спасибо за вашу помощь!