Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error when trying to use parfor (parallel for loop) in MATLAB

I am dealing with a very huge matrix and so wanted to use parallel computing in MATLAB to run in clusters. Here I have created a sparse matrix using:

Ad = sparse(length(con)*length(uni_core), length(con)*length(uni_core));

I have a written function adj using which I can fill the matrix Ad. Every time the loop runs, from the function adj I get a square symmetric matrix which is to be assigned to the Ad from 3682*(i-1)+1 to 3682 *(i-1)+3682 in the first index and similarly in the second index. This is shown here:

parfor i = 1:length(con)
  Ad((3682*(i-1))+1:((3682*(i-1))+3682), ...
     (3682*(i-1))+1:((3682*(i-1))+3682)) = adj(a, b, uni_core);
end

In a normal for loop it is running without any problem. But in parfor in parallel computing I am getting an error that there is a problem in using the sliced arrays with parfor.

like image 765
sushma Avatar asked Jan 21 '23 04:01

sushma


2 Answers

Outputs from PARFOR loops must either be reduction variables (e.g. calculating a summation) or "sliced". See this page in the doc for more.

In your case, you're trying to form a "sliced" output, but your indexing expression is too complicated for PARFOR. In a PARFOR, a sliced output must be indexed by: the loop variable for one subscript, and by some constant expression for the other subscripts. The constant expression must be either :, end or a literal scalar. The following example shows several sliced outputs:

x3 = zeros(4, 10, 3);
parfor ii = 1:10
    x1(ii) = rand;
    x2(ii,:) = rand(1,10);
    x3(:,ii,end) = rand(4,1);
    x4{ii} = rand(ii);
end

In your case, your indexing expression into Ad is too complicated for PARFOR to handle. Probably the simplest thing you can do is return the calculations as a cell array, and then inject them into Ad on the host side using a regular FOR loop, like so:

parfor i = 1:length(con)
   tmpout{i} = ....;
end
for i = 1:length(con)
   Ad(...) = tmpout{i};
end
like image 172
Edric Avatar answered Jan 30 '23 23:01

Edric


Edric has already explained why you're getting an error, but I wanted to make another suggestion for a solution. The matrix Ad you are creating is made up of a series of 3682-by-3682 blocks along the main diagonal, with zeroes everywhere else. One solution is to first create your blocks in a PARFOR loop, storing them in a cell array. Then you can combine them all into one matrix with a call to the function BLKDIAG:

cellArray = cell(1,length(con));  %# Preallocate the cell array
parfor i = 1:length(con)
  cellArray{i} = sparse(adj(a,b,uni_core));  %# Compute matrices in parallel
end
Ad = blkdiag(cellArray{:});

The resulting matrix Ad will be sparse because each block was converted to a sparse matrix before being placed in the cell array.

like image 38
gnovice Avatar answered Jan 31 '23 00:01

gnovice