0
votes

I am trying to parallelize pagerank using matlab parfor command as shown below.

However, the line which is marked by ** ** and is also written below:

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

is causing this error:

"Undefined function 'p_t1' for input arguments of type 'int32'."

When I comment it out, the code works. When I replace the parfor with a normal for, it works again. What is the problem?

Thanks

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)
1
In parfor, every iteration should be independent of each other. I think you code can be rewritten to reflect that. I think now index variable value is probably out of bounds for p_t1, hence you are getting that error. However, without running the code, I can't be sure. Ok, after examining more, I can see that the maximum value in L can be 7, which is more than the length of p_t1, which is 6. - Autonomous
I think that L{j} is a vector (something like a list? ) with different size for every j and that is causing the problem. Would that be the reason? How can I solve it? - Haris
Even if L{j} would have been a vector, I don't see why it would cause a problem because p_t0(j)/con_size(j) is still a scalar (a single number). You should think why an entry in L{j} is greater than the length of p_t1. - Autonomous
I changed the question, I fixed some bugs and now it gives me another error "Undefined function 'p_t1' for input arguments of type 'int32'." What is the cause for this one? - Haris

1 Answers

0
votes

Each variable inside parfor loop must be classified into one of several categories. Your p_t1 variable cannot be classified as any. It appears that you are trying to accumulate result in this variable across multiple iterations, which can be done using reduction variables. This is possible only if the result does not depend on the order of iterations (which appears to be the case in your example), but as you can see from the documentation, only certain types of expressions are allowed for reduction variables - mostly just simple assignments. In particular, you cannot index into a reduction variable - neither on the left-hand side, nor on the right-hand side of the assignment.

Matlab should be also producing plenty of warnings and M-Lint (statical code analyzer) warnings to highlight this issue.

You need to re-write your code so that Matlab could clearly classify each variable used inside parfor into one of the allowed categories.