2012-06-27 8 views
86

En mi reciente work con Gibbs sampling, he estado haciendo un gran uso del RVar que, en mi opinión, proporciona una interfaz casi ideal para la generación de números aleatorios. Lamentablemente, no he podido utilizar Repa debido a la imposibilidad de usar acciones monádicas en los mapas.Paralelo mapM en matrices Repa

Mientras que los mapas claramente monádicos no se pueden paralelizar en general, me parece que RVar puede ser al menos un ejemplo de una mónada donde los efectos se pueden paralelizar con seguridad (al menos en principio; no estoy muy familiarizado con el funcionamiento interno de RVar). A saber, quiero escribir algo como lo siguiente,

drawClass :: Sample -> RVar Class 
drawClass = ... 

drawClasses :: Array U DIM1 Sample -> RVar (Array U DIM1 Class) 
drawClasses samples = A.mapM drawClass samples 

donde A.mapM sería algo como,

mapM :: ParallelMonad m => (a -> m b) -> Array r sh a -> m (Array r sh b) 

Si bien está claro cómo podría funcionar esto depende de manera crucial de la aplicación de RVar y de su subyacente RandomSource, en principio, uno pensaría que esto implicaría dibujar una nueva semilla aleatoria para cada hilo engendrado y continuar como de costumbre.

Intuitivamente, parece que esta misma idea podría generalizarse a algunas otras mónadas.

Entonces, mi pregunta es: ¿Se podría construir una clase ParallelMonad de mónadas para la cual los efectos se pueden paralelizar con seguridad (presumiblemente habitada por, al menos, RVar)?

¿Qué aspecto podría tener? ¿Qué otras mónadas podrían habitar en esta clase? ¿Han considerado otros la posibilidad de cómo esto podría funcionar en Repa?

Finalmente, si esta noción de acciones paralelas monádicas no se puede generalizar, ¿alguien ve alguna buena manera de hacer que esto funcione en el caso específico de RVar (donde sería muy útil)? Renunciar al RVar para el paralelismo es una solución muy difícil.

+1

Supongo que el punto de fricción es "dibujar una nueva semilla aleatoria para cada hilo engendrado": ¿cómo debería funcionar este paso y cómo deberían fusionarse las semillas una vez que todos los hilos regresen? –

+1

La interfaz RVar casi seguramente necesitaría algunas adiciones para acomodar el engendrar un generador nuevo con una semilla determinada. Es cierto que no está claro cómo funciona la mecánica de este trabajo y parece bastante 'RandomSource' específico. Mi intento ingenuo de dibujar una semilla sería hacer algo simple y probablemente muy incorrecto, como dibujar un vector de elementos (en el caso de 'mwc-random') y agregar 1 a cada elemento para producir una semilla para el primer trabajador, agregue 2 para el segundo trabajador, etc. lamentablemente inadecuado si necesita entropía de calidad criptográfica; con suerte si solo necesitas una caminata aleatoria. – bgamari

+0

He podido hacer algo similar a lo que estás pidiendo usando 'fillChunkedIOP'. – kosmikus

Respuesta

4

Probablemente no sea una buena idea hacer esto debido a la naturaleza inherentemente secuencial de los PRNG. En su lugar, es posible que desee transición del código de la siguiente manera:

  1. Declare una función de IO (main, o lo que sea).
  2. Lee todos los números aleatorios que necesites.
  3. Pase los números (ahora puros) a sus funciones de reparación.
+0

¿Sería posible grabar en cada PRNG en cada hilo paralelo para crear independencia estadística? –