Pregunta

Tengo algunos códigos Fortran90 paralelos en los cuales cada hilo necesita generar la misma secuencia de números aleatorios.

Tengo un generador de números aleatorios que parece no ser seguro para los subprocesos, ya que, para una semilla dada, no puedo repetir los mismos resultados cada vez que ejecuto el programa.

Navegué sin éxito (casi) por toda la web en busca de algún código de un RNG seguro para subprocesos. ¿Podría alguien proporcionarme (el enlace a) el código de uno?

Gracias de antemano!

¿Fue útil?

Solución

Un buen generador de números pseudoaleatorios para Fortran90 se puede encontrar en Biblioteca estadística de vectores de Intel Math Kernel . Son hilos seguros. Además, ¿por qué tiene que ser seguro para subprocesos? Si quieres que cada hilo obtenga la misma lista, crea una instancia de un nuevo PRNG para cada hilo con la misma semilla.

Otros consejos

Los generadores de números aleatorios más repetibles necesitan un estado de alguna forma. Sin estado, no pueden hacer lo que viene después. Para estar seguro de subprocesos, necesita una forma de mantener el estado usted mismo (es decir, no puede ser global).

Cuando dices " necesita generar la misma secuencia de números aleatorios " quieres decir que

  • ¿Cada hilo necesita generar un flujo de números idénticos al otro hilo? Esto implica elegir la semilla antes de quitar los hilos, y luego crear una instancia de un PRNG local en cada hilo con la misma semilla.

o

  • ¿Quieres poder repetir la misma secuencia de números entre diferentes ejecuciones de los programas, pero cada hilo genera su propia secuencia independiente? En este caso, aún no puede compartir un solo PRNG porque la secuencia de operación del hilo no es determinista. Así que siembre un PRNG único con una semilla conocida antes de lanzar hilos, y utilícelo para generar las semillas iniciales para los hilos. Luego crea una instancia de los generadores locales de subprocesos en cada subproceso ...

En cada uno de estos casos, debe observar lo que Neil Butterworth digamos acerca de las estadísticas: la mayoría de las garantías habituales de que el PRNG desea afirmar no son confiables cuando la mezcla de flujos se genera de esta manera.


En ambos casos, necesita un PRNG de subproceso local. No sé qué hay disponible en f90 ... pero también puede escribir su propio (lookup Mersenne Twister , y escribe una ruta que tome el estado guardado como un parámetro ...).

En Fortran 77, esto se vería algo así como

      function PRNGthread (state)

      double state(statesize)

c stuff happens here which uses and manipulates the state vector...

      PRNGthread = result
      return 

y cada uno de tus hilos debe mantener un vector de estado separado, aunque todos usarán el mismo valor inicial.

Entiendo que necesita que cada hilo produzca la misma secuencia de números aleatorios.

Un muy buen generador pseudoaleatorio que generará un flujo de números reproducibles y es bastante rápido es el MT19937 . Solo asegúrese de generar la semilla antes de generar los hilos, pero genere una instancia separada del MT en cada hilo (haga que la instancia del hilo MT sea local). De esa manera se garantizará que cada MT producirá la misma secuencia de números.

¿Qué hay de SPRNG ? Aunque no lo he intentado yo mismo.

Codifiqué una versión Fortran 90 segura para subprocesos del Mersenne Twister / MT19973. El estado del PRNG se guarda en un tipo derivado (randomNumberSequence), y utiliza procedimientos para inicializar el generador u obtener el siguiente elemento de la secuencia.

http: //code.google.com/p/i3rc-monte-carlo-model/source/browse/trunk/Code/RandomNumbersForMC.f95

Las alternativas parecen ser:

  • Use un objeto de sincronización (como un mutex) en la semilla del generador valor. Esto desafortunadamente serializar su código en los accesos a generador
  • Utilice el almacenamiento local de subprocesos en el generador por lo que cada hilo tiene su propio semilla - esto puede causar estadísticas problemas para su aplicación
  • Si su plataforma soporta un adecuado operación atómica, usar eso en el semilla (probablemente no lo hará, sin embargo)

No es una lista muy alentadora, lo sé. Y para agregarlo, no tengo idea de cómo implementar ninguno de ellos en FORTRAN.

Este artículo https://www.cmiss.org/openCMISS/wiki/RandomNumberGenerationWithOpenMP no solo se enlaza con una implementación de Fortran, sino que menciona los puntos clave necesarios para hacer que un PRNG sea utilizable con hilos. El punto más importante es:

La versión Fortran90 de Ziggurat tiene varias variables y matrices con el atributo 'GUARDAR'. Para paralelizar el RNG uniforme, entonces, parece que los cambios necesarios son para hacer estas matrices de variables con un valor separado para cada subproceso (tenga cuidado con el intercambio falso). Luego, cuando se llama a la función PRNG, debemos pasar el número de hilo y usar el valor de estado correspondiente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top