MATLAB: Building sparse matrix inside parfor

parforsparse

I'm building a large sparse matrix in smaller pieces. Unfortunately the pieces overlap a bit. At the moment I'm building each piece to match the final size and after the loop I sum the pieces together. I have tried following approaches
1) I tried summing up sparse matrixes inside parfor. Bad idea. Produces full matrix.
2) Build index vectors for each piece of the matrix and combine the index vectors inside parfor. Then use one sparse command after the loop to build the final matrix. This, unfortunately, is rather slow. The reason might be the repetitive entries that the sparse command needs to sum up.
3) Build sparse matrix of each piece and store them in cell array inside parfor. Then sum up the sparse matrixes inside regular for loop. This is the best so far; fast and reliable. (See the pseudocode below.)
4) This is the problematic case: Build sparse vectors out of each piece and store them in cell array. Then sum up the sparse vectors inside regular for loop, and reshape to matrix. Unfortunately for larger systems it crashes with
Error using parallel_function (line 598)
Error during serialization
Error stack:
remoteParallelFunction.m at 31
As a for loop it runs just fine.
Below is some pseudocode to shed light on what I'm doing:
First option 3) that always works.
Aset = cell(1,Nsets) ;
parfor S=1:Nsets
% Do lots of stuff to get iind, jind, Aval

Aset{S} = sparse( iind, jind, Aval, Ndof, Ndof );
end
A = Aset{1};
for S=2:Nsets
A = A + Aset{S} ;
end
Option 4) that gives the error:
Aset = cell(1,Nsets) ;
parfor S=1:Nsets
% Do lots of stuff to get iind, jind, Aval
matind = iind +Ndof*( jind-1 );
Aset{S} = sparse( matind, ones(size(matind)), Aval, Ndof*Ndof, 1 ) ;
end
A = Aset{1};
for S=2:Nsets
A = A + Aset{S} ;
end
A = reshape(A,Ndof,Ndof) ;
Any ideas why option 4 crashes? How should I do this to gain speed?
The size of the final matrix, i.e. Ndof, is few millions. Number of matrix pieces, i.e. Nsets, is 10 to 30. For option 3 it takes roughly 30 seconds to sum the matrixes of size Ndof=4000000.

Best Answer

  • NEW:
    I think I have a possible workaround. Instead of using sparse on each iteration, build up the matind and aval vectors in the parfor loop and call sparse once at the end:
    Nsets = 12;
    Ndof = 1e6;
    matind = cell(12,1);
    Aval = cell(12,1);
    parfor S=1:Nsets
    % Do lots of stuff to get iind, jind, Aval
    iind = ceil(Ndof*rand(Ndof,1)) ;
    jind = ceil(Ndof*rand(Ndof,1)) ;
    Aval{S} = 100*randn(Ndof,1);
    matind{S} = iind +Ndof*( jind-1 );
    end
    matind = vertcat(matind{:});
    Aval = vertcat(Aval{:});
    A = sparse(matind,ones(numel(matind),1),Aval,Ndof*Ndof,1);
    A = reshape(A,Ndof,Ndof);
    spy(A)