How do you organize data from a parfor loop?

7 views (last 30 days)
I'm looking to run a script that has nested for loops in it using parallel processes to speed things up. I need the data to be organized by the indexes. I've been using a 3D array to do this with normal for loops. Im curious if theres a way to get the same results using parfor loops (or any parallel computing alternative).
My code looks something like this, but I want a way to do this same thing using parfor (or something similar):
nlower = 2;
nupper = 4;
tlower = 3;
tupper = 7;
iterations = 6;
%rows are the results for each iteration
%columns are for each size of t
%layers are for each size of n
someVariable = zeros(iterations, (tupper - tlower + 1), (nupper - nlower + 1));
for n = nlower:nupper
for t = tlower:tupper
for iter = 1:iterations
someVariable(iter, (t-tlower + 1), (n - nlower + 1)) = myFunction(iter, t, n);
end
end
end
someVariable %displays the variable to verify results
someVariable =
someVariable(:,:,1) = 6 7 8 9 10 7 8 9 10 11 8 9 10 11 12 9 10 11 12 13 10 11 12 13 14 11 12 13 14 15 someVariable(:,:,2) = 7 8 9 10 11 8 9 10 11 12 9 10 11 12 13 10 11 12 13 14 11 12 13 14 15 12 13 14 15 16 someVariable(:,:,3) = 8 9 10 11 12 9 10 11 12 13 10 11 12 13 14 11 12 13 14 15 12 13 14 15 16 13 14 15 16 17
function value = myFunction(iter, t, n)
value = iter+t+n;
end

Accepted Answer

2Lindsay2
2Lindsay2 on 26 May 2023
Edited: 2Lindsay2 on 26 May 2023
I have actually figure out a method to do this. I'll post it here to help anyone else out that may run into this.
I solved it by creating another matrix to store the function outputs and the indexes. Then in another loop the data can be organized. I'm open to a more elegant way of doing this though.
nlower = 2;
nupper = 4;
tlower = 3;
tupper = 7;
iterations = 6;
numOfT = tupper - tlower + 1;
numOfN = nupper - nlower + 1;
%rows are the results for each iteration
%columns are for each size of t
%layers are for each size of n
someVariable = zeros(iters, numOfT, numOfN);
VALUES = [];
for n = nlower:nupper
for t = tlower:tupper
parfor iter = 1:iterations
% someVariable(iter, (t-tlower + 1), (n - nlower + 1)) = myFunction(iter, t, n);
[val, I, T, N] = myFunction(iter, t, n);
VALUES = [VALUES; [val, iter, t, n]];
end
end
end
[lenV,~] = size(VALUES);
for i = 1:lenV
row = VALUES(i, 2);
col = VALUES(i, 3)-tlower + 1;
layer = VALUES(i, 4) - nlower + 1;
someVariable(row, col, layer) = VALUES(i,1);
end
someVariable
function [value] = myFunction(iter, t, n)
value = iter+t+n;
end

More Answers (1)

Edric Ellis
Edric Ellis on 30 May 2023
You can do this more directly by flattening the parfor loop, and using a combination of ind2sub and reshape. The idea is as follows:
  1. Instead of a triple-loop, run a single loop over a "linear index"
  2. Use ind2sub to map back from the "linear index" to co-ordinates
  3. Use reshape to undo "linear index" piece
Like this:
% dims is the list of sizes in each of 3 dimensions
dims = [iterations, tupper - tlower + 1, nupper - nlower + 1];
parfor idx = 1:(prod(dims))
% idx is the linear index - map this back to co-ordinates back
% in the original dimensions
[xi, xt, xn] = ind2sub(dims, idx);
% Store the result by linear index
out(idx) = myFunction(xi, xt + tlower - 1, xn + nlower - 1);
end
% reshape gets the output matrix back to the right size
someVariable2 = reshape(out, dims);
% Check we got the right answer
assert(isequal(someVariable, someVariable2))

Community Treasure Hunt

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

Start Hunting!