MPI: rand() gives the same constant numbers across all processes in every run
Asked Answered
T

2

7

I would like to ask a question about rand() in the context of (Open)MPI. We were given an implementation task in our parallel programming course - create an MPI application in which all participant processes chose one leader (randomly - they have to "vote"). My program looks like this:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
#include <mpi.h>

int main (int argc, char *argv[]) {
    int rank, size, vote, result;

    MPI_Init(&argc, &argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    vote = rand(); // Each process' vote.
    printf("%d: %d\n",rank+1, vote); // Only for debugging purposes here.

    MPI_Allreduce(&vote, &result, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
    result = (result & INT_MAX) % size + 1; // Select the leader.

    printf("Process %*d/%d: %d is the leader.\n", (int)(ceil(log10(size+1))), rank+1, size, result);

    MPI_Finalize();
    return 0;
}

The problem is, when I compile and run it using OpenMPI1.6, every process' vote is 1804289383, no matter how many processes is the program started with. The number is always the same in every new run of the program. Thus, if I run mpirun -np 7 ./a.out, the leader is always number 5, if I run it with -np 8, the first process is always the leader and so on...

Could please anyone explain me what am I doing wrong and how to fix this behaviour?

Thank you very much.

Thereinafter answered 19/5, 2014 at 16:14 Comment(2)
Just use a proper PRNG and give it a per-process seed. rand is hopelessly bad, even when seeded.Natividadnativism
@Natividadnativism rand is bad, but not "generates the same sequence on distinct processes in subsequent runs" bad. It's more than suitable for the task at hand, and the single line of code that solves the OP's problem is a lot easier than importing any third-party RNG could possibly be.Chamness
B
26

You have to seed your random number generator, eg

srand(time(NULL) + rank);
Blend answered 19/5, 2014 at 16:18 Comment(2)
Oh my, thank you... this was a really dumb mistake.Aurochs
You need a different seed for each process though, so be carefulNeedlewoman
G
1

You are not providing a seed to you random function. The 'usual' seed is time(NULL) although you might want to check something that a bit more flexible, like Mersenne Twister.

A good random number generator for C

Golda answered 19/5, 2014 at 16:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.