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.