OK, this is really weird.
I have an MPI program where each process must generate random numbers in a fixed range (the range is read from a file). It happens that even if I sow each process with a different value, and the numbers generated by rand() differ in each process, the expression for generating random numbers still gives the same sequence between them.
Here are all the relevant codes:
// 'rank' will be unique for each process int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); // seed the RNG with a different value for each process srand(time(NULL) + rank); // print some random numbers to see if we get a unique sequence in each process // 'log' is a uniquely named file, each process has its own log << rand() << " " << rand() << " " << rand() << std::endl; // do boring deterministic stuff while (true) { // waitTimeMin and waitTimeMax are integers, Max is always greater than Min waitSecs = waitTimeMin + rand() % (waitTimeMax - waitTimeMin); log << "waiting " << waitSecs << " seconds" << std::endl; sleep(waitSecs); // do more boring deterministic stuff }
Here is the output of each process with three processes generating numbers in the range [1.9].
process 1:
15190 28284 3149 waiting 6 seconds waiting 8 seconds waiting 9 seconds waiting 4 seconds
process 2:
286 6264 3153 waiting 6 seconds waiting 8 seconds waiting 9 seconds waiting 4 seconds
process 3:
18151 17013 3156 waiting 6 seconds waiting 8 seconds waiting 9 seconds waiting 4 seconds
Thus, while rand() explicitly generates different numbers, the expression for computing waitSecs still evaluates the same sequence for all processes. What's even weirder: if I run the program again with the same parameters, only the first 3 random numbers change, the rest of the "random" sequence will be the same in every run! Changing the range of numbers will obviously lead to a different result from this, but the same parameters always give the same sequence between processes and between execution: with the exception of the first three numbers.
What the hell is going on here?
EDIT: To just make sure this is simplified random generation and / or low range, I replaced the random generation with this line:
waitSecs = waitTimeMin + (int)((double)rand() / ((double)RAND_MAX + 1) * (waitTimeMax - waitTimeMin));
And he began to generate numbers in the range of [1.99]. Here is the result:
process 1:
7833 3798 10977 waiting 1 seconds waiting 20 seconds waiting 58 seconds waiting 35 seconds waiting 82 seconds waiting 18 seconds
process 2:
25697 14547 10980 waiting 1 seconds waiting 20 seconds waiting 58 seconds waiting 35 seconds waiting 82 seconds waiting 18 seconds
process 3:
10794 25295 10984 waiting 1 seconds waiting 20 seconds waiting 58 seconds waiting 35 seconds waiting 82 seconds waiting 18 seconds
Same. Could this just be rand() really bad?
EDIT2: The same when creating numbers from 1 to 10000.