7
$\begingroup$

Is it possible to register a some "initialization code" to be run on any newly started parallel kernel?

This would be similar to how ParallelNeeds registers a package to be loaded right away when a new kernel is started, or how DistributeDefinitions and SetSharedVariable/SetSharedFunction take effect immediately on a newly launched subkernel.

Why do I need this?

Mainly to make sure that certain global settings are set. Examples: $Path, $Assumptions, $MaxExtraPrecision, etc. The biggest reason is really $Path.

Note that kernels may get launched automatically, even during ongoing computations. When a kernel dies unexpectedly, it will be re-launched.

Related:

$\endgroup$
9
$\begingroup$

I found two ways to do this. Both are undocumented, so all usual caveats apply.

Parallel`Developer`$InitCode

This can be done using Parallel`Developer`$InitCode. While undocumented, this does appear fairly stable.

First trigger loading the parallel tools:

Parallelize;

?Parallel`Developer`$InitCode

ReleaseHold[$InitCode] is run on every new subkernel for user initialization.

Just set

Parallel`Developer`$InitCode = Hold[your; code; here]

One problem with this is that it will be run only after packages registered by ParallelNeeds are loaded. Thus it cannot be used to set the $Path.

Parallel`Protected`AddInitCode

The following is a hack messing with the internals of the parallel tools package. Use at your own risk. The advantage is that it can be used to set $Path, to be used with ParallelNeeds.

Parallelize; (* trigger loading *)

?Parallel`Protected`AddInitCode

AddInitCode[code] sends code to running subkernels and uses AppendInitCode to remember it.

?Parallel`Protected`AppendInitCode

AppendInitCode[code] is for load-time setup of init code.

Register code to be run at kernel startup like this:

Parallel`Protected`AddInitCode[
 Parallel`Client`HoldCompound[your; code; here],
 True (* permanent *)
]

The second argument controls whether this init code should survive Parallel`Developer`ClearKernels[]. This argument can be omitted and defaults to False.

This is the same mechanism that ParallelNeeds uses. Make sure to register the $Path change before evaluating ParallelNeeds.

SetSharedVariable/SetSharedFunction also make use of AddInitCode.

These initialization code will be registered in the following variables:

Parallel`Kernels`Private`$clientCode
Parallel`Kernels`Private`$clientOriginalCode

$clientOriginalCode contains code set to persist even after ClearKernels[]. $clientCode contains all init code, both persistent and not.

$\endgroup$

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.