# Call ParallelSubmit from inside a parallel kernel

I am scheduling myFun[x] to evaluate every couple of seconds in a parallel kernel with ParallelSubmit and ParallelDeveloperQueueRun[], where it sometimes triggers (multiple) additional follow-up functions, which need to be submitted for evaluation on the next available parallel kernels, i.e.

CreateScheduledTask[ParallelDeveloperQueueRun[],.1]


But nesting ParallelSubmit in this way doesn't seem to work.

Is there a way to submit an expression for evaluation on the next available parallel kernel from within a parallel kernel?

EDIT Per Szabolcs comment I tried the following code which seems to behave as intended.

<< ParallelDeveloper
ClearKernels[]; CloseKernels[]; LaunchKernels[4];
SetSharedVariable[x, y, z]

f[u_] := ParallelSubmit[ReleaseHold[u]];
SetSharedFunction[f]

Dynamic[Refresh[{x, y, z}]]

x = y = z = 0;

ParallelSubmit[x = $KernelID]; ParallelSubmit[f[Hold[Pause[5]; z =$KernelID]]; y = \$KernelID;]

• I believe this can only be done on the main kernel. Thus you need to call back to the main kernel. One way to do this is to use SetSharedFunction, which effectively marks a function as evaluatable on the main kernel only. I have not tested this though. – Szabolcs May 18 '18 at 11:10
• @Szabolcs thank you for the tip, I did not know that SetSharedFunction restricted functions to the main kernel only. It seems to do the trick. – user19218 May 18 '18 at 12:31
• When a subkernel encounters a shared function, it sends it back to the main kernel for evaluation, then retrieves the result. The same with shared variables: their value is always read/set on the main kernel. This provides an additional data exchange method between subkernels (whose memory is otherwise entirely isolated). The drawback is that all these callbacks to the main kernel can have a severe performance impact. Cross-kernel communication is generally slow, so typically we want to reduce it as much as possible. – Szabolcs May 18 '18 at 12:35

I believe this can only be done on the main kernel. Thus you need to call back to the main kernel. One way to do this is to use SetSharedFunction, which effectively marks a function as evaluatable on the main kernel only.