在MPI C

时间:2019-04-18 22:47:25

标签: c random mpi

我正在尝试生成随机数并将这些数字分配给每个任务中的数组。我想确保不同任务中的随机数不同。我该如何实现?

如果每个MPI任务都使用随机数(例如我附带的代码)初始化其自己的数组,那么这些数字在任务之间是否不同?

我知道我可以生成大量随机数并广播到每个任务,但这可能会导致大型数组的内存问题。

非常感谢您提供任何信息。

void initialize(float* inarray, int n){
    int i;
    for (i=0; i<n; i++){
            inarray[i] = random() / (float)RAND_MAX;
        }
    }
}

void main(int argc, char* argv[]){

    MPI_Comm comm=MPI_COMM_WORLD;
    int numnodes, myid, ierr;
    ierr=MPI_Init(&argc, &argv);
    ierr=MPI_Comm_size(comm, &numnodes);
    ierr=MPI_Comm_rank(comm, &myid);

    int n = 100;
    float *x = malloc(sizeof(float)*n);
    initialize(x, n);

    ierr=MPI_Finalize();
}

3 个答案:

答案 0 :(得分:0)

这是我的愚蠢解决方案: 在一个循环中,一个MPI任务创建随机数,然后顺序发送给其他任务。对我来说,这就像手动播放一样,但是节省了一些内存。

    if (myid == 0){
        int i;
        for (i=0; i<n; i++){
            initialize(x, n);
            if (i != myid){
                MPI_Send(&x[0], n, MPI_FLOAT, i, 0, comm);
            }
        }
    }else{
        MPI_Recv(&x[0], n, MPI_FLOAT, 0, 0, comm, MPI_STATUS_IGNORE);
    }

答案 1 :(得分:0)

(伪)随机数生成器必须是种子,并且每个等级上都有不同的种子。

在我的环境中(CentOS 7):

chunk_store

产生

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

#include <mpi.h>

int main(int argc, char *argv[]) {
    int rank;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    srand(rank+1);
    float f = (float)random() / (float)RAND_MAX;
    printf ("%d: %f\n", rank, f);
    MPI_Finalize();
    return 0;
}

答案 2 :(得分:0)

因此,这实际上比预期的要复杂。有两个问题:

首先,假设您有40个mpi进程,都需要使用0和1之间的均匀分布绘制10个数字。然后,如果使用单条链绘制400个数字,则将获得相当好的均匀分布。但是,如果您只画10个数字,您可能不会。从40个链中抽取10个数字并不完全等同于从一个链中抽取400个数字。但是仅当您需要很好地控制发行版时,才会出现此问题。

第二,假设您想用数字研究给定的问题。您必须测试的是求解器的收敛性。为此,您需要查看您的求解器在精细化分辨率下的性能是否良好。因此,您需要以保持相同的低频(如果您在傅立叶空间中考虑)的方式生成不同的实现(您的随机数)。为此,您需要确保在给定位置上的随机数(假设您的400中的327数)始终是相同的,而与您使用的进程数量无关。

这两个问题都表明,简单地从链中提取连续数字不是一个好的解决方案。

所以您可以做的是: -使用单条链 -第一个过程使用链的前10个数字。 -第2步使用链的第11到20号。 ......

但这意味着给定的过程必须丢弃给定数量的链元素。如果使用“常规”随机数生成器,则丢弃n个数是O(n)操作。这意味着您无法并行处理问题。您需要使用随机生成器,其中包含一种丢弃O(1)中n次绘制的方法。您可以在网上找到很多这样的方法。或者,您也可以自己编写代码(但这实际上是在尝试重新发明轮子)。

我使用的我自己: https://rdrr.io/cran/sitmo/
但这是针对C ++的,但是请确保您可以找到C的版本或仅使用C ++来编写此版本。