2011-11-29 5 views
8

Sono interessato all'esecuzione della stessa funzione che esegue alcune valutazioni di monte carlo con valori diversi degli argomenti sui kernel multipli in modo parallelo. Voglio anche assicurarmi che l'intera funzione venga eseguita sullo stesso kernel, senza che i calcoli all'interno della funzione vengano distribuiti attraverso i kernel. Ad esempio, supponiamo di avere una funzione (volutamente semplificato)Programmazione parallela in Mathematica

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]; 

Ora voglio eseguire f [m1, m2], f [m3, m4], f [M5, M6], f [m7, m8 ] f [m9, m10] su cinque diversi kernel senza trasferimento di informazioni attraverso questi kernel, cioè con un flusso separato di numeri casuali tra i diversi kernel.

Come si può farlo all'interno di Mathematica?

+1

Avere ragazzi divertenti, sono seduto questo fuori. –

+1

@ Mr.Wizard: Non è divertente quando non sei in giro con cui competere però :) –

risposta

3

Forse puoi seminare singoli kernel con $KernelID e $ProcessID?

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

E questo dovrebbe andare a cinque diversi kernel (l'opzione FinestGrained prende ogni valutazione di un nuovo kernel):

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

Quando i (max 5) è maggiore del numero di kernel (8), tuttavia si verificheranno dei problemi, ad esempio f[13,14],, utilizzare lo stesso seme di f[2,3].

+0

Non è questo ciò che accade di default? Vedi [here] (http://reference.wolfram.com/mathematica/tutorial/RandomNumberGeneration.html), dice * "Per i calcoli paralleli è molto vantaggioso avere un generatore su ciascun thread che produce numeri casuali indipendenti dai generatori su altri thread In Mathematica a ogni thread utilizzato in un calcolo parallelo verrà assegnato un indice univoco che parte da zero (e in genere passa sequenzialmente a $ ProcessorCount) che verrà utilizzato per fornire semi e generatori diversi su ciascun thread. "* – Szabolcs

+0

Desidero tutto il calcolo all'interno di una funzione si verifica sullo stesso kernel. Se la funzione comporta più estrazioni casuali (diciamo 10000), tutte dovrebbero provenire dallo stesso flusso. – asim

2

Credo che quello che stai cercando è BlockRandom.

Secondo il 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. 

allora si potrebbe avere:

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