It appears that it is possible to launch additional kernels (or close existing ones) during a parallel calculation. The newly launched kernels will be utilized for the rest of the calculation.
Here's a simple way to test and illustrate this (in a fresh kernel):
LaunchKernels[2]
Parallelize[
Table[Pause@RandomInteger[20]; $KernelID, {i, 8}],
Method -> "FinestGrained"
]
Now use Evaluation -> Interrupt Evaluation...
to interrupt the
evaluation and go into a subsession. In the subsession evaluate
$KernelCount (* check that we only have 2 kernels *)
LaunchKernels[4] (* launch 4 more *)
Return (* return from the dialog *)
Notice that when the Table[]
finally finishes, we get results between
1 and 6 (I got {2, 1, 6, 5, 4, 3, 2, 1}
). This means that all 6 kernels have been utilized during the rest of the evaluation, even though some kernels were only launched in the middle of the calculation.
It is also possible to close some kernels during the calculation. In another test I got the following messages ...
... and the calculation seemed to finish correctly.
Question: Is it safe to do this? Can this break anything if the timings are wrong?
Consider some code like this:
(* This uses LaunchKernels[] to launch more kernels
as compute resources become available: *)
manageKernels[] := ...
(* ensure that manageKernels[] is always evaluated on the master kernel *)
SetSharedFunction[manageKernels]
Parallelize[
Table[manageKernels[]; compute[i], {i, 100}],
Method -> "FinestGrained"
]
Is this going to be safe? What if manageKernels[]
uses CloseKernels[]
as well?