# DistributeDefinitions and synchronization in Mathematica 10

The command DistributeDefinitions[z] installs all current definitions for z on the local kernels. A simple example: we assign the value 1 to z in the mainkernel, distribute the definitions of z and inspect the values of z in the subkernels. All are 1.

z=1;
DistributeDefinitions[z];
{z, ParallelEvaluate[z]}
(* {1,{1,1,1,1}} *)


The function DistributeDefinitions does not establish a synchronization between the local kernels and the main kernel. Therefore, when change z to 2 in the main kernel, in the subkernels the value of z is still 1:

z=2;
{z, ParallelEvaluate[z]}
(* {2,{1,1,1,1}} *)


Anyway, that was the result in Mathematica 8 and Mathematica 9. But Mathematica 10.4 does at least some synchronization. There we obtain

z=1;
DistributeDefinitions[z];
{z, ParallelEvaluate[z]}
z=2;
{z, ParallelEvaluate[z]}
(* {1,{1,1,1,1}} *)
(* {2,{2,2,2,2}} *)


Does someone know what exactly has changed in DistributeDefinitions? The documentation does not help me, but I might have overlooked a release note.

Edit

After some further playing, I found the following buggish behaviour:

z=4;
DistributeDefinitions[z]
(* {z} *)

{z, ParallelEvaluate[z]}
(* {4,{4,4,4,4}} *)

ParallelEvaluate[ValueQ[z]]
(* {True, True, True, True} *)

ParallelEvaluate[Clear[z]]
(*  {Null,Null,Null,Null} *)

ParallelEvaluate[ValueQ[z]]
(* {False,False,False,False} *)

{z, ParallelEvaluate[z]}
(* {4,{4,4,4,4}} *)

{z, ParallelEvaluate[1+z^2]}
(* {4,{17,17,17,17}} *)

ParallelEvaluate[ValueQ[z]]
(* {False,False,False,False} *)


We can do numerical computations with variables that do not have a value!

• I didn't know about this change ... DistributeDefinitions does register distributed symbols, see ParallelDeveloper$DistributedDefinitions. Perhaps this is a good starting point for researching what happens. – Szabolcs Apr 3 '16 at 8:57 • @FredSimons Thanks for the UPDATE. It is strange that there are no standard "Updated in 2016 (10.4)" footnotes both at the Documentation page for ParallelEvaluate and DistributedContexts. – Alexey Popkov Apr 4 '16 at 18:58 ## 1 Answer Thanks to Wolfram Technical Support, I am now able to answer my own question and explain the results I showed in the Edit. My question was: what exactly has changed in DistributeDefinitions? The answer is simple: nothing. What I observed is due to a undocumented change in ParallelEvaluate. Since version 10.4, it has an option DistributedContexts with default value $DistributedContexts. So when we call ParallelEvaluate, the first thing that happens now is that the required definitions are automatically distributed to the subkernels. In version 10.3 and earlier, ParallelEvaluate did not automatically distribute definitions.

That explains why the command

z=1; DistributeDefinitions[z];
z=2; ParallelEvaluate[z]


now returns {2,2,2,2} instead of {1,1,1,1} as in earlier versions.

Then, in the Edit, I reported some buggish results. It already follows from the comment of Alexey Popkov that these results have nothing to do with the the new behaviour of ParallelEvaluate. Now I feel both amused and ashamed about this Edit, for it it not bug at all. It is a simple consequence of something that I have seen already hundreds of times.

This is essentially what I did in the Edit.

z=4; DistributeDefinitions[z];
ParallelEvaluate[z]
(* {4,4,4,4} *)
ParallelEvaluate[Clear[z]];
ParallelEvaluate[z]
(* {4,4,4,4} *)


The second result highly surprised me, since I cleared the values of z in the subkernels.

Before Mathematica 10.4, the explanation is simple. The result of the second ParallelEvaluate[z] is the list {z,z,z,z}. In the main kernel, z still has the value 4, so this list evaluates further to the output {4,4,4,4}.

In Mathematica 10.4, we might think that the result of the second ParallelEvaluate[z] is due to another distribution of the definition of z. That this has not happened can be seen as follows:

ParallelEvaluate[ValueQ[z]]
(* {False,False,False,False} *)


Another distribution is only done when the value of z has changed, like here:

z=1;ParallelEvaluate[ValueQ[z]]
(* {True,True,True,True} *)


Therefore, also in Mathematica 10.4, the result {4,4,4,4} is due to a further evaluation of {z,z,z,z}.

• I still do not get why we get ParallelEvaluate[z] (* {4,4,4,4} *) after the Clear[z] and still ValueQ[z] is false. Which mechanism makes the 4 know to ParallelEvaluate[z] after ParallelEvaluate[Clear[z]] if not DistributeDefinitions? – Eisbär May 25 '16 at 10:35
• @Eisbär. After ParallelEvaluate[Clear[z]], the value of z in the subkernels is cleared, but in the main kernel the valueof z is still 4. Therefore, ParallelEvaluate[z] (which now does not redistribute the definition of z to the subkernels) returns the list {z,z,z,z} in the main kernel. But in the main kernel this list further evaluates to {4,4,4,4}. – Fred Simons Jun 5 '16 at 6:50
• Thats a tricky one, as it is not actually returning the true value as given by the parallel kernel but an interpretation of that by the master kernel. I have to rember that one. Thank you for elaborating. – Eisbär Jun 7 '16 at 6:47