8
votes

I am interested in running the same function that does some monte carlo evaluations with different values of the arguments on mulitple kernels in a parallel fashion. I also want to ensure that entire function runs on the same kernel, without the computations within the function being distributed across kernels. For example, suppose I have a function (deliberately simplified)

f[a_, b_] := Module[{}, RandomReal[{a, b}]]


In[1]:= LaunchKernels[]

Out[1]= {KernelObject[1, "local"], KernelObject[2, "local"], 
 KernelObject[3, "local"], KernelObject[4, "local"], 
 KernelObject[5, "local"], KernelObject[6, "local"], 
 KernelObject[7, "local"]}

SeedRandom[795132, Method -> "ParallelGenerator"];

m1 = 1; m2 = 2; m3 = 3; m4 = 4; m5 = 5; m6 = 6; m7 = 7; m8 = 8;

DistributeDefinitions[f, m1, m2, m3, m4, m5, m6, m7, m8];

I now want to run f[m1, m2], f[m3, m4], f[m5, m6], f[m7, m8] f[m9, m10] on five different kernels with no information transfer across these kernels, i.e, with a separate stream of random numbers across the different kernels.

How can one do this within Mathematica?

2
Have fun guys, I am sitting this one out. - Mr.Wizard
@Mr.Wizard: It's no fun when you're not around to compete with though :) - Mike Bailey

2 Answers

3
votes

Perhaps you can seed individual kernels with $KernelID and $ProcessID?

ParallelEvaluate[
 Print[$KernelID $ProcessID];
 SeedRandom[$KernelID $ProcessID]
]

And this should go to five different kernels (the FinestGrained option takes every evaluation to a new kernel):

ParallelTable[$KernelID -> f[2 i - 1, 2 i], {i, 5}, Method -> "FinestGrained"]

When i (max 5) is greater than the number of kernels (8), this is going to run into issues though, i.e. f[13,14] may use the same seed as f[2,3].

2
votes

I believe what you're looking for is BlockRandom.

According to the documentation,

BlockRandom[expr]
evaluates expr with all pseudorandom generators localized,
so that uses of SeedRandom, RandomInteger, and related functions
within the evaluation of expr do not affect subsequent pseudorandom sequences.

Then you might have:

f[a_, b_] := BlockRandom[{}, RandomReal[{a, b}]