Is the pile-up of ones into the elements of a matrix parallelizable by parfor?

1 view (last 30 days)
Hello,
Is there any way to do the following pile-up in matrix A using parfor?
A = zeros(1,J);
for i=1:n
j = f(i); % f returns index j = 1,2,...J
A(j) = A(j)+1;
end
Thanks in advance, Abi

Accepted Answer

Matt J
Matt J on 18 Feb 2013
Edited: Matt J on 18 Feb 2013
You don't really want the A(j)=A(j)+1 inside the PARFOR, because that's not a data parallel operation. Presumably f(i) is the hard computation, in which case you could do,
A=zeros(J,1);
j=ones(n,2);
parfor i=1:n
j(i,1) = f(i); % f returns index j = 1,2,...J
end
A=accumarray(j,1,size(A)).'
  6 Comments
Abi mehranian
Abi mehranian on 19 Feb 2013
Edited: Abi mehranian on 19 Feb 2013
Many thanks for your comments,
As i mentioned f returns the index j, which takes values between 1,..J. the function f is the most time consuming part. As you suggested, A should be pile up out side of the parfor loop. actually, i was doing that by another for loop, which in my case should go through 200 millions loops. Thanks to Matt, i guess accumarray is a prudent alternative to that for loop. Here is a sample test (with f as a vector). Merci,
J = 20; n = 8000;
A=zeros(J,1);
j=ones(n,2);
f=floor(1+rand(1,n)*J);
parfor i=1:n
j(i,1) = f(i); % f returns index j = 1,2,...J
end
A=accumarray(j,1,size(A)).'

Sign in to comment.

More Answers (1)

Jan
Jan on 19 Feb 2013
Edited: Jan on 19 Feb 2013
Assuming that f() is the most time-consuming part:
C = cell(1, n);
parfor iC = 1:n
C{iC} = f(iC);
end
A = zeros(1,J);
for iC = 1:n
index = C{iC};
A(index) = A(index) + 1;
end
Unfortunately I cannot test this, but collecting the results of f() in a cell should work, while A(j)=A(j)+1 cannot be performed inside a PARFOR due to a concurrent data access to the values of A.
  3 Comments
Matt J
Matt J on 19 Feb 2013
Edited: Matt J on 19 Feb 2013
You could actually split the accumarray computation using PARFOR, but that means broadcasting multiple copies of A from the labs. For large J, I don't know if it would be worth it. My example below involves the cell-splitting utility MAT2TILES, available here
j=ones(n,2);
parfor i=1:n
j(i,1) = f(i); % f returns index j = 1,2,...J
end
m=matlabpool('size');
chunksize=ceil(J/m);
jC = mat2tiles(j,[chunksize, inf]);
parfor i=1:length(jC)
A=A+accumarray(jC{i},1,[J,1]);
end
Abi mehranian
Abi mehranian on 20 Feb 2013
Thank you so much, that's fine too, but my 32 GB machine gets out of memory for J = 1e8, in any case, accumarray is much faster than a for-loop.

Sign in to comment.

Categories

Find more on Tables in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!