0

I just wanted to generate on every processor different random numbers. But instead of that, I get the same random numbers on every processor.

Here is the output for 4 processors:

Processor 0: 0 random number is 21
Processor 0: 1 random number is 62
Processor 0: 2 random number is 27
Processor 0: 3 random number is 90
Processor 0: 4 random number is 59

Processor 1: 0 random number is 21
Processor 1: 1 random number is 62
Processor 1: 2 random number is 27
Processor 1: 3 random number is 90
Processor 1: 4 random number is 59

Processor 2: 0 random number is 49
Processor 2: 1 random number is 21
Processor 2: 2 random number is 62
Processor 2: 3 random number is 27
Processor 2: 4 random number is 90

Processor 3: 0 random number is 49
Processor 3: 1 random number is 21
Processor 3: 2 random number is 62
Processor 3: 3 random number is 27
Processor 3: 4 random number is 90

This is what my code looks like:

    #include <stdlib.h>
    #include <time.h>
    #include <stdio.h>
    #include <mpi.h>

    typedef struct{
        int myrank;
        int numprocs;
        int *range;
    } SubD;

    void compRange(SubD *s, int myrank, int numprocs){
        s->myrank = myrank;
        s->numprocs = numprocs;

        // Allocate memory
        s->range = malloc((numprocs+1) * sizeof(int));
        // Fill range with random numbers between 0 and 99
        for(int p=0; p<=numprocs; p++){
            s->range[p] = rand()%100;
        }

        for(int p=0; p<s->numprocs; p++){
            if(myrank == p){
            for(int k=0; k<=numprocs; k++){
                printf("Processor %d: %d random number is %d\n", p, k, s->range[k]);
            }
            printf("\n");
            }
        }
    }


    int main(int argc, char **argv){

        int myrank;           // Rank of processor
        int numprocs;         // Number of processes
        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
        MPI_Comm_size(MPI_COMM_WORLD, &numprocs);

       time_t t;     
        /* Intializes random number generator */
       srand((unsigned) time(&t));

        SubD s;
        compRange(&s, myrank, numprocs);

        MPI_Finalize();
        return 0;
}

So my question is: How do I get on every processor different random numbers?

Gilfoyle
  • 3,282
  • 3
  • 47
  • 83
  • 2
    I would move the `srand((unsigned) time(&t));` to the begin of `main`. Also note that `rand()` is not threadsafe. – mch Jan 19 '17 at 10:26
  • https://linux.die.net/man/3/rand says that you should use `rand_r()`. – mch Jan 19 '17 at 10:27
  • 1
    The main thing is that if you seed the RNG with `time` all instances started within the same second will actually produce exactly the same random number sequences. Try to seed using `/dev/random` or even not at all. – tofro Jan 19 '17 at 10:31
  • @mch That works somehow. But most random numbers are still the same on every processor – Gilfoyle Jan 19 '17 at 10:33
  • @tofro I do not know what you mean by "Try to seed using `/dev/random`". Can you please give me some more hints. – Gilfoyle Jan 19 '17 at 10:35
  • Every unixoid system normally has a device called `/dev/dandom`. Open it, read `sizeof(unsigned int)` bytes into a `unsigned int` variable from it that you can use as argument for `srand`, and you have the most random seed your computer can provide. – tofro Jan 19 '17 at 10:44
  • Most Linux libs have a function `getrandom` that does exactly that. – tofro Jan 19 '17 at 10:51
  • Check the keyword **distributed seeding**. There are some papers about it as it's not that simple and it's also very dependent on the underlying PRNG (if you care about the underlying known defects of some PRNG and want high-quality output; example: correlation between seeds in MersenneTwister). – sascha Jan 19 '17 at 11:11
  • @mch, this is MPI, not OpenMP. Thread-safety is a non-issue as each rank runs in its own process. – Hristo Iliev Jan 20 '17 at 09:12

0 Answers0