Does anybody know what's going on in this simple code using parfor in matlab? Thanks,
I sliced a matrix into four arrays and want to update elements in each array independently
Here is a simple version:
a = zeros(4,4);
parfor i = 1:4
j = 2;
a(j,i) = 3;
end
error:Valid indices for 'a' are restricted in parfor loops;
however,
this works:
a = zeros(4,4);
parfor i = 1:4
a(2,i) = 3;
end
another simpler nonworking version with the same error:
a = zeros(4,4);
parfor i = 1:4
a(i,i) = 3;
end
in my application, index j is generated independently for each array through some algorithm
Just my two cents: As @mmumbos already explained, what you're trying to achieve is not possible this way, but certain workarounds can still apply.
Let's assume you need to implement something like the following (which is the permutation of a linear transformation of matrix A
):
n=10;
A=rand(n,n);
B=zeros(n,n);
parfor i=1:n,
j=(i<=5)*(2*(i-1)+1)+(i>5)*(2*(i-5));
B(j,i) = my_function(A(i,:));
end
Try instead the following:
parfor i=1:n,
B_temp(i,:) = my_function(A(i,:));
end
Then, you don't really need to construct matrix B
; you can access it using B_temp
using an ''index table'' which is simply constructed as follows:
J=zeros(n,1);
parfor i=1:n,
J(i) = (i<=5)*(2*(i-1)+1)+(i>5)*(2*(i-5));
end
Then B(i)
is accessed via B_temp(J(i))
.
Revisiting your last (counter)example, let's see how you can work it around:
n=4;
diag_A = zeros(n,1);
parfor i=1:n,
diag_A(i)=3; % or any function of i
end
Then, whenever you need to access the ''i''-th diagonal element of A
, you access instead diag_A(i)
. For such cases it is convenient to create a function along the following lines:
function a = access_matrix(A, diag_A, i, j)
if (i!=j),
a = A(i,j);
else
a = diag_A(i);
end
end
Until MATLAB improves the implementation of parfor
, such workarounds will (unfortunately) be necessary in lots of cases.
What you are trying to achieve seems not to be possible.
According to the matlab documentation:
When you use other variables along with the loop variable to index an array, you cannot set these variables inside the loop. In effect, such variables are constant over the execution of the entire parfor statement. You cannot combine the loop variable with itself to form an index expression.
MATLAB Documentation Source
So all variables you use to index your array, other than the loop variable have to be constant for the entire loop.
Since it hasn't been mentioned yet, here's a link which is really helpful for diagnosing these types of issues: Classification of Variables in Parfor. These issues arise when MATLAB cannot classify the variables into the rigid definitions it outlines on that page.
What's happening here is that it does not know how to slice up the "slice variable" A before the loop. Think about programming the parallel implementation yourself. What you would want to do is cut-up A into even pieces that you know other processors won't touch, and then give them to different CPUs to act indpendently. MATLAB looks at your loop and doesn't know how to do this because it doesn't know what j is until it's running the program. It's a limitation of MATLAB. Another case where the same thing happens if you use complex coefficients like A(i*j,:). Once again it doesn't know how to split it up.
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