In the examples below, the variable status
is an Association
object that is supposed to be shared by three concurrent kernels.
The assignment status[$KernelID] = 1
fails if I run it within ParallelEvaluate
:
status = <||>;
SetSharedVariable[status];
ParallelEvaluate[status[$KernelID] = 1;];
status
Set::noval: Symbol status in part assignment does not have an immediate value. Set::noval: Symbol status in part assignment does not have an immediate value. Set::noval: Symbol status in part assignment does not have an immediate value. <||>
An equivalent assignment works fine if I run it outside of ParallelEvaluate
, as shown below. (NB: In the snippet below, I use ParallelEvaluate
only to get the values of $KernelID
for the various kernels; the assignments to status
happen outside ParallelEvaluate
).
status = <||>;
SetSharedVariable[status];
Scan[(status[#] = 1) &, ParallelEvaluate[$KernelID]];
status
<|1 -> 1, 2 -> 1, 3 -> 1|>
Is there a way to share an Association
object among all kernels in such a way that each kernel can modify the object?
FWIW, I am immediately interested in the use-case where each kernel assigns only to the key corresponding to its $KernelID
.
UPDATE: FWIW, the problem seems to be specific to Association
s; a similar scenario using a list instead of an association works fine:
statusList = ConstantArray[Null, Max[ParallelEvaluate[$KernelID]]];
SetSharedVariable[statusList];
ParallelEvaluate[statusList[[$KernelID]] = 1;];
statusList
{1, 1, 1}
(This looks more and more like a bug to me... In this case, I suppose I should specify that I'm using 10.4.1.0 Linux x86 (64-bit).)
ParallelSubmit
andParallel`Developer`QueueRun[]
. I'll see if I can piece together a workaround from the developer stuff. Also it complains thatstatus
is protected for me, which definitely suggests this is a bug. $\endgroup$Set::wrsym : Symbol status is Protected.
FWIW,ParallelEvaluate[Attributes[status]]
returns a list with a bunch of{Protected}
entries. $\endgroup$