Matlab с использованием Evalin в 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-loop, matlab выдает ошибку, что индекс превышает размеры матрицы, что должно означать, что переменная x пуст (или не оценивается правильно). Странно то, что когда я запускаю цикл как обычно forпетля, все отлично работает. Я знаю о проблемах прозрачности с parforтока, отсюда я поставил evalin в отдельную функцию.

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

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

1 ответ

Решение

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

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

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

extractData = cell(size(var));
for iVar = 1:numel(var)
    extractData{iVar} = data(var{iVar});
end
Другие вопросы по тегам