Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating random numbers in parallel with identical engines fails

Tags:

c++

c++11

openmp

I am using the RNG provided by C++11 and I am also toying around with OpenMP. I have assigned an engine to each thread and as a test I give the same seed to each engine. This means that I would expect both threads to yield the exact same sequence of randomly generated numbers. Here is a MWE:

#include <iostream>
#include <random>

using namespace std;


uniform_real_distribution<double> uni(0, 1);
normal_distribution<double> nor(0, 1);


int main()
{
    #pragma omp parallel
    {
        mt19937 eng(0); //GIVE EACH THREAD ITS OWN ENGINE
        vector<double> vec;

        #pragma omp for
        for(int i=0; i<5; i++)
        {
            nor(eng);
            vec.push_back(uni(eng));
        }
        #pragma omp critical
        cout << vec[0] << endl;
    }



    return 0;
}

Most often I get the output 0.857946 0.857946, but a few times I get 0.857946 0.592845. How is the latter result possible, when the two threads have identical, uncorrelated engines?!

like image 314
BillyJean Avatar asked Mar 24 '23 08:03

BillyJean


1 Answers

You have to put nor and uni inside the omp parallel region too. Like this:

#pragma omp parallel
{
    uniform_real_distribution<double> uni(0, 1);
    normal_distribution<double> nor(0, 1);
    mt19937 eng(0); //GIVE EACH THREAD ITS OWN ENGINE
    vector<double> vec;

Otherwise there will only be one copy of each, when in fact every thread needs its own copy.

Updated to add: I now see that exactly the same problem is discussed in this stackoverflow thread.

like image 140
TonyK Avatar answered Apr 06 '23 16:04

TonyK