3
$\begingroup$

The documentation shows the following example to "Remove a distributed definition..."

Example

Oh, course this doesn't work without redefining the function prior to re distributing the definition. The following does work:

ClearAll[f];
f[x_] := Labeled[Framed[x^2], $KernelID]
DistributeDefinitions[f];
ParallelMap[f, {1, 2, 3, 4}]

and will give the same output as the above screen clip. OK, but...

This seems a very cumbersome way to do this and just doesn't seem right at all.

It would seem clearer to me if one could call back the distribution of a function definition, something like UnDistributeDefinitions[], to withdrawal the function from remote kernels rather than needing to clear the function in the main kernel, redefine it, then redistribute it.

I came across this issue as I looked to move a DistributeDefinitions[] into a function that will run a bunch of other functions from a standalone cell in a notebook. To test whether it would work, I need to clear all the functions I wanted to distribute or restart the kernel.

Just seems a messy way to do things. So, does a way exist to clear definitions in remote kernels without clearing them in the main kernel?

$\endgroup$
6
  • $\begingroup$ What's wrong with g=f; ParallelDo[Clear[f],{<numberofkernels>}]; f=g; $\endgroup$
    – chris
    Commented Oct 16, 2012 at 19:02
  • $\begingroup$ @chris -- Certainly, one can do workarounds. But it doesn't address my concern. My point and concern follow from the definition of a function in the main kernel and the distribution of the definition representing very different kinds of things. Why should one have to redefine a function when one just wants to get it out of a remote kernel? Maybe not a big deal. Just seems odd. $\endgroup$
    – Jagra
    Commented Oct 16, 2012 at 21:00
  • $\begingroup$ It seems I don't get your point. Do you understand what happens here: a = 1; ParallelEvaluate[a] and OwnValues[a] and now ParallelEvaluate[OwnValues[a]]? Your example from the doc does not only show the undistribution, it clears f completely. If this would not be done, then the main-kernel would be called when you eval f on the subkernels. Can you clear again for me, what your question is? $\endgroup$
    – halirutan
    Commented Oct 17, 2012 at 2:49
  • $\begingroup$ @halirutan -- If I have defined a function and distributed it to subkernels and then close the subkernels it does not clear the definition in the main kernel. This makes sense in a parallel computing environment where subkernels might come and go. Now with regard to my question, Mathematica seems inconsistent in that no way apparently exists to clear function definitions in subkernels without also clearing them in the main kernel. Maybe Clear[] should have a "RemoteKernels" parameter something like: Clear[f,"RemoteKernels"] that wouldn't kill the function definition in the main kernel. $\endgroup$
    – Jagra
    Commented Oct 17, 2012 at 3:37
  • $\begingroup$ @Jagra, And writing ParallelEvaluate[Clear[f]] is not an option? $\endgroup$
    – halirutan
    Commented Oct 17, 2012 at 8:00

2 Answers 2

5
$\begingroup$

Let me summarize the issues from the comments above and hopefully clear this for you. We start with the definition of f which calculates something and prints the $KernelID. We don't distribute this definition

f[x_] := {x^2, $KernelID};

Now we call ParallelMap and see that the function is called by the subkernels. While $KernelID of the main kernel is 0, the id of the subkernels is a positive integer

ParallelMap[f, {1, 2, 3, 4}]
(* {{1, 2}, {4, 2}, {9, 1}, {16, 1}} *)

This works because ParallelMap distributes automatically the definition of f. To suppress this behavior there is an option for most parallel functions: DistributedContexts. This can be set to None.

To answer your question: to clear the definition on the sub-kernels, you only have to use

ParallelEvaluate[Clear[f]]
ParallelMap[f, {1, 2, 3, 4}]
(* {{1, 0}, {4, 0}, {9, 0}, {16, 0}} *)

You see, that now the evaluating kernel has always the id 0. What's more interesting is, that now the definition of f is not redistributed automatically by ParallelMap. In fact, after clearing the definition on the sub-kernels even an explicit call to

DistributeDefinitions[f];
ParallelMap[f, {1, 2, 3, 4}]
(* {{1, 0}, {4, 0}, {9, 0}, {16, 0}} *)

is useless and f gets evaluated on the main kernel. This seems to be because f hasn't changed. You have to check the output of DistributeDefinitions to see whether some symbols was really distributed. Of course you can always make the definition explicitly on the sub-kernels with ParallelEvaluate[f[x_] := {x^2, $KernelID};] and everything is fine again.

Be careful when you play with distributing, redistributing or deleting definitions on the sub-kernels. It's not always clear on the first glance what happens and especially, who evaluates your expression.

$\endgroup$
1
  • $\begingroup$ That really helps clarify what goes on across the whole parallel environment. Your closing sentences "Be careful when you play with distributing, redistributing or deleting definitions on the sub-kernels. It's not always clear on the first glance what happens and especially, who evaluates your expression." go directly to my reason for posting the question. Thanks. $\endgroup$
    – Jagra
    Commented Oct 18, 2012 at 12:43
0
$\begingroup$

Well if I am not wrong, the above solutions, as the one in the documentation do not solve the problem, in that DistributeDefinitions also distribute variables on which the original f depended.

One can clear f manually on parallel kernels, but one should also recursively clear all the other variables, which becomes cumbersome.

A proper function for instance would be UnDistributeDefinitions[f,Recursive->True/False], or even UndistributeDefinitions[] -> All distributions are cleared.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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