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
.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With