Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.
6974 Discussions

initializing multiple random number generator streams for parallel code

cygnetmama
Beginner
505 Views

I am using the set of 6024 Mersenne Twister pseudorandom number generators to generate multiple, independent sequences of random numbers within an OpenMP parallel region.  When I initialized the random number generators, I wrote the streams to file so I could be sure they were different.  One of the two numbers is unique for each stream, but the second number is identical for all streams.  For example, for 4 threads, I get

 thread           3 stream -2039061504          49
 thread           1 stream -2039060224          49
 thread           2 stream -2039060864          49
 thread           0 stream -2039057664          49

Is this okay or does it mean I have done something wrong?  A stripped down version of the relevant code appears below.

Thank you!

      PROGRAM Rng19_2
      USE ModApril2013
      USE Tmod19
      USE omp_lib
      USE MKL_VSL_TYPE
      USE MKL_VSL
     
      IMPLICIT NONE
      TYPE(VSL_STREAM_STATE)::stream

      MySd=23    
      nruns=200
      CALL omp_set_num_threads(nThrds) 


      !$OMP PARALLEL  DEFAULT(NONE)     
     &PRIVATE (irun,URVs,id,errcode,stream,ThrdSd)          
     &SHARED (nruns,MySd) 
        
      id = omp_get_thread_num() 
      ThrdSd = MySd + id
      errcode=vslnewstream(stream, VSL_BRNG_MT2203+id,  ThrdSd)
      write(79,*) 'thread', id, 'stream', stream
     
      !$OMP DO SCHEDULE(STATIC,nruns/nThrds)
      NewPopulationLoop: DO irun=1,nruns       
      
        errcode=VDRngUniform(VSL_RNG_METHOD_UNIFORM_STD,stream,nURVs,
     &  URVs,0.0_DP,1.0_DP) 
      
      END DO NewPopulationLoop
      !$OMP END DO      
     
      errcode=vsldeletestream( stream )

      !$OMP END PARALLEL

      END PROGRAM Rng19_2

0 Kudos
4 Replies
Ilya_B_Intel
Employee
505 Views

The numbers you printed if combined togather identify the stream, and it is ok if some of them are identical but not all at once.

We run your code (with some dependencies removed) and that should work as intended.

In our run we see the following numbers with streams:

 thread id=           3 stream= -1140778368       32645
 thread id=           2 stream=  -939521408       32645
 thread id=           0 stream=    47153152           0
 thread id=           1 stream= -1006630272       32645

The numbers generated by those streams in threads are different. Here are first 2 numbers from different threads:

URVs=  0.327342507662252       0.882119875401258
URVs=  0.256897222949192       0.952226318651810
URVs=  0.515935511561111       0.137881062459201
URVs=  0.584926510695368       0.183347462909296

0 Kudos
cygnetmama
Beginner
505 Views

Thank you so much for helping me with this!

I have one more question, please.  Did you use a different seed or did you use MySd=23 .  I would have thought with the same seed that you would have been able to replicate my results.

Thanks again.

0 Kudos
Eugeny_G_Intel
Employee
505 Views

Hello cygnetmama,

Here is a program we used (it is your test-case simplified so that we can run it). The seed is ThrdSd = MySd + id. And we generate 2 random values. There is no sense to print stream. It is just internal library id, different for each stream. There is sense to print what stream generates, i.e. URVs in our case, and it is reproduceable on same processor, if the stream initialized with same method, seed, etc.

      include 'mkl_vsl.f90'

      PROGRAM Rng19_2
      USE omp_lib
      USE MKL_VSL_TYPE
      USE MKL_VSL
    
      !IMPLICIT NONE
      TYPE(VSL_STREAM_STATE)::stream
      REAL(8)               ::URVs(2)
      INTEGER               ::ThrdSd
      REAL(8)               ::A0,A1

      A0=0.0
      A1=1.0
      nURVs=2
      MySd=23   
      nruns=2
      CALL omp_set_num_threads(4)  !nThrds

      !$OMP PARALLEL  DEFAULT(NONE)
     &PRIVATE (irun,URVs,id,errcode,stream,ThrdSd)
     &SHARED (nruns,nURVs,MySd,A0,A1)

      id = omp_get_thread_num()
      ThrdSd = MySd + id
      errcode=vslnewstream(stream, VSL_BRNG_MT2203+id,  ThrdSd)
      write(*,*) 'thread id=', id, 'stream=', stream

        errcode=VDRngUniform(VSL_RNG_METHOD_UNIFORM_STD,stream,
     &  nURVs,URVs,A0,A1)
      write(*,*) 'thread id =',id, 'URVs=', URVs

      errcode=vsldeletestream( stream )

      !$OMP END PARALLEL

      END PROGRAM Rng19_2
 

Currently output is (we run on Haswell):

 thread id=           0 stream=    19902464           0
 thread id=           3 stream= -1946154368       32553
 thread id=           1 stream= -1811936640       32553
 thread id=           2 stream= -1744827776       32553
 thread id =           1 URVs=  0.515935511561111       0.137881062459201
 thread id =           2 URVs=  0.584926510695368       0.183347462909296
 thread id =           0 URVs=  0.256897222949192       0.952226318651810
 thread id =           3 URVs=  0.327342507662252       0.882119875401258
 

0 Kudos
cygnetmama
Beginner
505 Views

Okay, now I have a better understanding.  Thank you very much for helping me!

0 Kudos
Reply