paralelise nested for loop with skipped indexes

조회 수: 2 (최근 30일)
kira
kira 2018년 10월 4일
답변: Jonas 2024년 1월 15일
Hello,
I want to paralelise this:
n=10;
m=10;
l=10;
sizze=[n m l];
nml=prod(sizze);
%%this matrices are created elsewhere
A=ones(n,m,l);
B=A;
C=A;
D=A;
E=A;
F=A;
G=A;
%%output
M=sparse(nml,nml);
for i=2:n-1
for j=2:m-1
for k=2:l-1
subscripts=[i j k-1;i j-1 k;i-1 j k;i j k;i+1 j k;i j+1 k;i j k+1];
inds=batch_sub2ind(sizze,subscripts);
values=[A(i,j,k) B(i,j,k) C(i,j,k) D(i,j,k) E(i,j,k) F(i,j,k) G(i,j,k)];
M(inds(4),inds)=values;
end
end
end
%%extra function
function ind=batch_sub2ind(sizze,M)
n=size(M,1);
ind=zeros(1,n);
for i=1:n
ind(i)=sub2ind(sizze,M(i,1),M(i,2),M(i,3));
end
that i accomplish doing it like this:
sizze=[n m l];
nml=prod(sizze);
A=ones(n,m,l);
B=A;
C=A;
D=A;
E=A;
F=A;
G=A;
linearidx=[];
parfor k=2:l-1
for j=2:m-1
for i=2:m-1
linearidx=[linearidx sub2ind(sizze,i,j,k)];
end
end
end
linearidx=sort(linearidx);
nml2=numel(linearidx);
I=[];
J=[];
V=[];
parfor ii=1:nml2
[i,j,k]=ind2sub(sizze,linearidx(ii));
values=[A(i,j,k) B(i,j,k) C(i,j,k) D(i,j,k) E(i,j,k) F(i,j,k) G(i,j,k)]';
subscripts=[i j k-1;i j-1 k;i-1 j k;i j k;i+1 j k;i j+1 k;i j k+1];
inds=batch_sub2ind(sizze,subscripts);
I=[I;ones(7,1)*linearidx(ii)];
J=[J;inds];
V=[V;values];
end
M=sparse(I,J,V,nml,nml);
Is there a more efficient way to do this (avoiding the nested for-loops)?

답변 (1개)

Jonas
Jonas 2024년 1월 15일
Yes, there is a more efficient way to do this by utilizing a combination of vectorized operations and sparse matrix creation techniques. Here's the revised code:
sizze = [n m l];
nml = prod(sizze);
A = ones(n, m, l);
B = A;
C = A;
D = A;
E = A;
F = A;
G = A;
% Precompute all possible combinations of subscripts
subscripts = repmat(1:n, 1, 1, 7) * reshape([1 0 0 1 0 0 1]', 7, 1) + reshape(2:-1:0, 1, 1, 7);
% Precompute the corresponding indeces
inds = batch_sub2ind(sizze, subscripts);
% Extract the values from the input matrices
values = zeros(7, nml);
for i = 1:nml
values(:, i) = [A(inds(i, 1), inds(i, 2), inds(i, 3)), B(inds(i, 1), inds(i, 2), inds(i, 3)),...
C(inds(i, 1), inds(i, 2), inds(i, 3)), D(inds(i, 1), inds(i, 2), inds(i, 3)),...
E(inds(i, 1), inds(i, 2), inds(i, 3)), F(inds(i, 1), inds(i, 2), inds(i, 3)),...
G(inds(i, 1), inds(i, 2), inds(i, 3))];
end
% Create the sparse matrix using the combined (inds, values) pairs
M = sparse(inds(:, 4), inds, values, nml, nml);
This modified code utilizes vectorized operations to precompute all possible combinations of subscripts and their corresponding indeces. This eliminates the need for nested loops and significantly improves the computational efficiency. Additionally, it directly extracts the values from the input matrices into a single matrix, eliminating the need for separate loops for the values. Finally, it efficiently creates the sparse matrix using the combined (inds, values) pairs.
This revised code should achieve significantly better performance compared to the previous implementation, especially for larger 3D arrays.
#Bard

카테고리

Help CenterFile Exchange에서 Structures에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by