2
$\begingroup$

It is well known that assignments to a variable shared between the main kernel and the subkernels are only executed by the main kernel. I suppose that when a subkernel has to assign to a shared variable, it sends the command to the main kernel for execution. Therefore, I was surprised to see a situation where the subkernel simply refused to do the assignment. Here is a highly simplified example.

demo[] := Module[{asc},
  Quiet[CloseKernels[]; LaunchKernels[2]];
  SetSharedVariable[asc];
  Print[Attributes[asc]];
  ParallelEvaluate[Print[Attributes[asc]]];
  asc=Association[{}];
  ParallelDo[AssociateTo[asc,$KernelID->0], {i,1,$KernelCount}];
  Print[asc];
  ParallelEvaluate[asc[$KernelID]++];
  Print[asc];
  ParallelEvaluate[AssociateTo[asc, $KernelID->1+asc[$KernelID]]];
  Print[asc];
]

In[6]:= demo[]
During evaluation of In[6]:= {Temporary}
(kernel 1) {Protected}
(kernel 2) {Protected}
During evaluation of In[6]:= <|2->0,1->0|>
(kernel 1) Set::wrsym :  Symbol asc$3017 is Protected.
(kernel 2) Set::wrsym :  Symbol asc$3017 is Protected.
During evaluation of In[6]:= <|2->0,1->0|>
During evaluation of In[6]:= <|2->1,1->1|>

I open two subkernels and construct a shared variable asc. The output shows that in the main kernel it has attribute Temporary, being a Module variable, but on the subkernels it has attribute Protected. Then I assign an association to asc, with keys the KernelID's and initial value 0 for each key. No problem.

Then on each subkernel I use the increment function for increasing the value of the KernelID. Both subkernels report that they cannot do that because of the variable is protected. But when on each subkernel I increase the value by using AssociateTo, it works.

Is there a simple explanation why we cannot use the increment function on the subkernels, or has it to be considered as a minor bug?

$\endgroup$
  • $\begingroup$ Looks like a bug to me. Try reaching out to Wolfram support, see what they say. $\endgroup$ – b3m2a1 Nov 25 '17 at 21:23
1
$\begingroup$

If you want do parallel computing, it's better to use immutable data but not mutable data.

In:

demo[] := Module[{asc, xs}, Quiet[CloseKernels[]; LaunchKernels[2]];
  SetSharedVariable[asc];
  Print[Attributes[asc]];
  ParallelEvaluate[Print[Attributes[asc]]];
  asc = Association[{}];

  xs = ParallelTable[$KernelID -> 0, {i, 1, $KernelCount}];
  AssociateTo[asc, xs];
  Print[asc];

  xs = ParallelTable[$KernelID -> asc[$KernelID] + 1, {i, 
     1, $KernelCount}];
  AssociateTo[asc, xs];
  Print[asc];

  xs = ParallelTable[$KernelID -> asc[$KernelID] + 1, {i, 
     1, $KernelCount}];
  AssociateTo[asc, xs];
  Print[asc];]
demo[]

Out:

{Temporary}
{Protected}
{Protected}
<|14->0,13->0|>
<|14->1,13->1|>
<|14->2,13->2|>
| improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks for your answer. I am not so familiar with mutable and immutable data, but I think I understand what you mean. However, that does not really answer my question. I am puzzled by the fact that in one situation the subkernels refuse to do an assignment to a shared variable and in another one they do assign. Have you any ideas about that? $\endgroup$ – Fred Simons Apr 29 '17 at 16:24
  • $\begingroup$ asc has the attribute protected when you do ParallelEvaluate. You can't change it during parallel evaluation. $\endgroup$ – UnchartedWorks Apr 29 '17 at 16:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.