2013-05-21 8 views
5

Mam problemy z używaniem tablic struct w pętli parla Matlaba. Poniższy kod ma 2 problemy nie rozumiem:Używanie macierzy struct w 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. To nie powiedzie się z powodu błędu Error using parallel_function (line 589) Insufficient number of outputs from right hand side of equal sign to satisfy assignment.
  2. Na wyjściu zmienna s jest wektorem, a nie tablicą (jak powinno być, nawet jeśli złamanie kodu przed zakończeniem).

EDIT problem zostanie rozwiązany, jeśli zainicjować tablicę struct do prawidłowej wielkości, przez:

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

Chciałbym jednak nadal być szczęśliwy, aby uzyskać wiedzę o problemie (np chodzi rajd bug, jak zasugerował Oleg Komarov)

+0

Do punktu 2, co masz na myśli „tablicę” zamiast „wektor”? W Matlabie nie ma różnicy. Wydaje mi się, że 's' powinno być macierzą 2x4' struct's na końcu tego kodu. – jazzbassrob

+0

Myślę, że to w rzeczywistości błąd i zalecam przesłanie [support equest] (http://www.mathworks.it/support/service_requests/contact_support.do?) I informowanie nas na bieżąco. – Oleg

+0

@jazzbassrob, wektor jest tablicą 1xd (lub dx1). –

Odpowiedz

3

Początkowo działało dobrze dla mnie, ale potem nie wiem co się stanie. Generalnie musisz być ostrożny z pętlami parfor i istnieje obszerna dokumentacja, jak wyrównać wszystko. Dwa różne słowa porad. Po pierwsze i najważniejsze, pętla parfor jest na zewnątrz pętli:

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 

Dwa, Matlab staje się bardzo wrażliwy na piśmie główną zmienną wyjściową (czyli zmienne zawarte w pętli parfor która jest indeksowana do pętli w twoim przypadku, s). Najpierw chcesz utworzyć sztuczną zmienną, która zawiera wszystkie informacje wewnętrzne, a następnie zapisuje do niej raz na końcu pętli. Przykład:

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 

Nie masz tu problem, ale może się komplikują w innych przypadkach

+0

Dlaczego parfor powinien znajdować się w zewnętrznej pętli? Jeśli mam zewnętrzną pętlę na indeksie [1,2] i wewnętrzną pętlę na indeksie [1, ..., 1000], wewnętrzna pętla, która jest dłuższa, nie będzie zrównoleglona, ​​czyż nie? –

+0

istnieje obciążenie ogólne związane z pętlami parfor, a są przypadki, w których będzie opłacalne posiadanie go w pętli wewnętrznej (szczególnie jeśli masz więcej niż dwie działające puli), ale generalnie powinieneś zorganizować kod tak, aby że pętla parfor znajduje się w zewnętrznej pętli. Przy puli 2, prawie zawsze będzie szybciej z parfor w zewnętrznej pętli (spróbuj i porównaj ...). – Rasman

+0

Dobra odpowiedź! W jakiś sposób, jeśli indeksujesz oryginalną strukturę za pomocą zmiennej "pętli parfor" (w tym przypadku 'j'), to działa. Indeksowanie w jakikolwiek inny sposób wydaje się nie działać. Na przykład 's (1, :)' nie działa, ale 's (j, :)' does! –

Powiązane problemy