"valid indices for 'a' are restricted in PARFOR loops" for unindexed struct?

58 次查看(过去 30 天)
For the following code:
parfor k = 1:2
a.b = k;
end
I'm getting the error "valid indices for 'a' are restricted in PARFOR loops"
But there is no indexing here. Could someone explain what I'm missing?
In case it's important, the code above comprises the entire script.
Edit: I found the documentation which explicitly states that you can't do what I'm trying to do:
You cannot create a structure in a parfor-loop using dot notation assignment.
It's not clear why, though.
Edit 2: Mathworks support has submitted an enhancement request to update the error message to something clearer in a future release.
MATLAB Version: 9.1.0.441655 (R2016b)

回答(1 个)

OCDER
OCDER 2018-7-16
编辑:OCDER 2018-7-16
parfor k = 1:2
a(k).b = k;
end
The reason a.b = k does NOT work is because when the parfor finishes, and there are, say N workers creating 1000 parallel versions of a.b = k, which one is going to be the final a.b? If 1000's of parallel universes converge into 1 universe, which universe will we be the "real" universe? Error error.
But, a(k).b = k works because each worker creates its own separate variable (or isolated universe), a(1).b, a(2).b, ..., a(N).b. No conflict issues.
In the example, this works too because temp is defined inside the parfor, which tell matlab "this is a temporary variable that's created in the parallel world - do not bring it to the real world"
parfor i = 1:4
temp = struct(); %What's created in the parallel world stays in the parallel world
temp.myfield1 = rand();
temp.myfield2 = i;
end
  7 个评论
OCDER
OCDER 2018-7-16
More examples for clarity (or confusion).
parfor k = 1:10 %<=== look for the iterator, 'k'
a(k) % sliced, I see a direct use of 'k'
a(k).b % sliced, I see a direct use of 'k' in the 1st level of a struct
a.b % NOT sliced. No use of 'k' anywhere
a.b(k) % Tricky. Not sliced at the 1st lv of struct 'a', but is sliced at 2nd lv 'a.b'.
% Matlab doesn't know if you want to save 'a' or treat as temporary var
a(k).b(k) % Tricky. Sliced variable! Sliced at 1st lv of struct a.
end
Hmm, yeah, the explanation isn't obvious as to why a.b = k is not just assumed to be a temporary variable. My guess is that structures are normally assumed to behave like objects that persistent across iteration, but parfor makes this assumption invalid. To prevent confusion, users have to be VERY CLEAR they know this structure will delete after each iteration unless it's sliced.
for j = 1:10
a.b = j; %structure "a" is created when j == 1, and it persists from here on out.
%a.b = 10 when loop finishes. No ambiguity.
end
parfor j = 1:10
a.b = j; %structure a is created 10 times at random order! a.b = 10, a.b = 2, ... a.b = 5.
%How do we assemble this back to a single "a" structure?
%Should this even be a single structure as an output?
%Was this a temporary variable?
%Let's just make this throw an error. Unclear how to return "a".
end
Evan
Evan 2018-7-17
编辑:Evan 2018-7-17
@OCDER I appreciate your perseverance. I stepped away from this for a day to give it a fresh look. I think I have thought of a logical reason why a.b=k doesn't work. If the struct a is defined before the parfor loop, it would seem strange for a.b=k to completely wipe the previous a object, whereas a=struct() does this explicitly. And it is not possible to know by looking at the code whether a will be in the workspace before the code is run (e.g. a load operation).
Or maybe someone from Mathworks will jump in and give the true reasoning. But in any case, I think I would have figured this out more quickly if the error message was more precise about what I was doing wrong. Hopefully the enhancement request goes through.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Loops and Conditional Statements 的更多信息

标签

产品


版本

R2016b

Community Treasure Hunt

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

Start Hunting!

Translated by