2013-05-21 4 views
5

У меня возникли проблемы с использованием структурных массивов в парфоре Matlab. Следующий код имеет 2 проблемы, которые я не понимаю:Использование структурных массивов в parfor

s=struct('a',{},'b',{}); 
if matlabpool('size')==0 
    matlabpool open local 2 
end 

for j = 1:2  
    parfor k=1:4 
    fprintf('[%d,%d]\n',k,j) 
    s(j,k).a = k; 
    s(j,k).b = j; 
    end 
end 
matlabpool close 
  1. Он завершается с ошибкой Error using parallel_function (line 589) Insufficient number of outputs from right hand side of equal sign to satisfy assignment.
  2. На выходе переменной s вектор, а не массив (как это должно быть, даже если разрывы кода перед завершением).

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

s=struct('a',cell(2,4),'b',cell(2,4)); 

Однако, я все еще был бы рад получить представление о проблеме (например, является его ралли, ошибка, о которой говорил Олег Комаров)

+0

Для точки 2, то, что вы имеете в виду «массив», а не «вектор»? В Matlab нет никакого различия. Мне кажется, что '' 'должна быть матрицей 2x4' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' – jazzbassrob

+0

Я думаю, что это на самом деле ошибка, и я рекомендую отправить [support equest] (http://www.mathworks.it/support/service_requests/contact_support.do?) И держать нас в курсе. – Oleg

+0

@jazzbassrob, вектор - массив 1xd (или dx1). –

ответ

3

Первоначально она работала нормально для меня, но потом я не знаю, что произойдет. В общем, вам нужно быть осторожным с петлями parfor, и есть достаточная документация о том, как выровнять все. Два разных совета. Во-первых, и что еще более важно, петля parfor находится на внешней стороне петли:

function s = foo 
s=struct('a',{},'b',{}); 

parfor j = 1:2  
    for k=1:4 
    fprintf('[%d,%d]\n',k,j) 
    s(j,k).a = k; 
    s(j,k).b = j; 
    end 
end 

Два, Matlab получает очень требователен написание главной переменной выхода (то есть переменная, содержащаяся в цикле parfor, который индексируется к петле, в вашем случае, s). Сначала вы хотите создать фиктивную переменную, которая хранит всю информацию о внутренней памяти, а затем записывает ее один раз в конце циклов. Пример:

function s = khal 
s=struct('a',{},'b',{}); 


parfor j = 1:2 
    dummy=struct('a',{},'b',{}); 
    for k=1:4 
    fprintf('[%d,%d]\n',k,j) 
    dummy(k).a = k; 
    dummy(k).b = j; 
    end 
    s(j,:) = dummy; 
end 

У вас нет проблемы здесь, но она может усложниться в других случаях

+0

Почему парфор должен быть во внешнем цикле? Если у меня есть внешний цикл на индексе [1,2] и внутренний цикл на индексе [1, ..., 1000], внутренний цикл, который длиннее, не будет распараллелен, не так ли? –

+0

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

+0

Хороший ответ! Как бы то ни было, если вы индексируете исходную структуру с помощью переменной среза в 'parfor loop' (в данном случае' j'), она работает. Индексирование каким-либо другим способом, похоже, не работает. Например, 's (1, :)' не работает, но 's (j, :)' делает! –

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