Ошибка при использовании Matlab parfor

Я пытаюсь распараллелить PageRank с помощью команды Matlab parfor, как показано ниже.

Тем не менее, строка, которая отмечена ** ** и также написана ниже:

p_t1(L{j,i}) = p_t1(L{j,i}) +constant;

вызывает эту ошибку:

«Неопределенная функция ‘p_t1’ для входных аргументов типа ‘int32’».

Когда я это комментирую, код работает. Когда я заменяю parfor на обычный for, он снова работает. В чем проблема?

Спасибо

S='--------------------------------------------------';
n = 6;
index=1;
a = [2 6 3 4 4 5 6 1 1];
b = [1 1 2 2 3 3 3 4 6];
a = int32(a);
b=int32(b);
a=transpose(a);
b=transpose(b);
vec_len=length(a);
%parpool(2);

for i=1:vec_len
    G(1,i)=a(i);
    G(2,i)=b(i);
    con_size(i)=0;
end
%n=916428

for j = 1:vec_len
   from_idx=a(j);
   con_size(from_idx)=con_size(from_idx)+1;
   L{from_idx,con_size(from_idx)}=b(j); 
end
% Power method
max_error=100;
p = .85;
delta = (1-p)/n;
p_t1 = ones(n,1)/n;
p_t0 = zeros(n,1);
cnt = 0;
tic

while max_error > .0001
   p_t0 = p_t1;
   p_t1 = zeros(n,1);

   parfor j = 1:n
      constant=p_t0(j)/con_size(j);
      constant1=p_t0(j)/n;

      if con_size(j) == 0
         p_t1 = p_t1 + constant1;
      else
         for i=1:con_size(j)  
            **p_t1(L{j,i}) = p_t1(L{j,i}) +constant;**
         end
      end
   end
   p_t1;
   sum(p_t1);
   p_t1 = p*p_t1 + delta;
   cnt = cnt+1;
   max_error= max(abs(p_t1-p_t0));
   %disp(S); 
end
toc

%delete(gcp)

person Haris    schedule 24.04.2016    source источник
comment
В parfor каждая итерация должна быть независимой друг от друга. Я думаю, что ваш код можно переписать, чтобы отразить это. Я думаю, что теперь значение переменной index, вероятно, выходит за пределы для p_t1, поэтому вы получаете эту ошибку. Однако, не запуская код, я не могу быть уверен. Хорошо, изучив больше, я вижу, что максимальное значение в L может быть 7, что больше, чем длина p_t1, которая равна 6.   -  person Autonomous    schedule 24.04.2016
comment
Я думаю, что L {j} - это вектор (что-то вроде списка?) с разным размером для каждого j, и это вызывает проблему. Будет ли это причиной? Как я могу это решить?   -  person Haris    schedule 24.04.2016
comment
Даже если бы L{j} был вектором, я не понимаю, почему это вызвало бы проблему, потому что p_t0(j)/con_size(j) по-прежнему скаляр (одиночное число). Вы должны подумать, почему запись в L{j} больше, чем длина p_t1.   -  person Autonomous    schedule 24.04.2016
comment
Я изменил вопрос, исправил некоторые ошибки, и теперь он выдает еще одну ошибку. Неопределенная функция «p_t1» для входных аргументов типа «int32». В чем причина этого?   -  person Haris    schedule 24.04.2016


Ответы (1)


Каждая переменная внутри цикла parfor должна быть классифицирована в одну из нескольких категорий. Ваша переменная p_t1 не может быть классифицирована как любая. Похоже, вы пытаетесь накопить результат в этой переменной за несколько итераций, что можно сделать с помощью переменные сокращения. Это возможно только в том случае, если результат не зависит от порядка итераций (что, по-видимому, имеет место в вашем примере), но, как вы можете видеть из документации, для редукционных переменных разрешены только определенные типы выражений - в основном просто простые задания. В частности, нельзя индексировать редукционную переменную — ни в левой, ни в правой части присваивания.

Matlab также должен выдавать множество предупреждений и предупреждений M-Lint (статический анализатор кода), чтобы подчеркнуть эту проблему.

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

person nirvana-msu    schedule 24.04.2016