在MPI C中为每个进程生成随机数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在MPI C中为每个进程生成随机数相关的知识,希望对你有一定的参考价值。
我试图生成随机数,并在每个任务中将这些数字分配给数组。我想确保不同任务中的随机数不同。我怎么能实现这一目标?
如果每个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();
}
这是我的愚蠢解决方案:在循环中,一个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);
}
(伪)随机数发生器必须被播种,并且每个等级上有不同的种子。
在我的环境中(CentOS 7):
#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;
}
产生
0: 0.840188
1: 0.700976
2: 0.561380
3: 0.916458
4: 0.274746
5: 0.135439
6: 0.486904
7: 0.352761
8: 0.206965
9: 0.565811
10: 0.926345
11: 0.785600
12: 0.632643
13: 0.999498
14: 0.354973
15: 0.215437
事实上,这比预期的要复杂得多。有两个问题:
首先,假设您有40个mpi进程,所有进程都需要绘制10个数字,使用0和1之间的均匀分布。然后,如果您使用单个链条绘制400个数字,您将获得非常好的均匀分布。但如果你只抽出10个数字,你可能不会。从40链中拉出10个数字并不严格等同于从一个链中绘制400个数字。但是,只有当您需要对分发进行良好控制时,才会出现此问题。
其次,假设您希望以数字方式研究给定问题。你需要测试的是你的求解器的收敛。为此,您需要查看求解器在精细分辨率下是否表现良好。所以你需要的是以一种保持相同低频的方式产生不同的实现(你的随机数)(如果你想在傅立叶空间中)。要做到这一点,你需要确保在给定位置的随机数(比如400的327号)始终是相同的,无论你使用多少进程。
这两个问题都表明,从链中简单地绘制连续数字并不是一个好的解决方案。
所以你可以做的是: - 使用一个链 - 第一个过程使用链的前10个数。 - 第二个过程使用链的第11到第20个数字。 ......
但这意味着给定的过程必须丢弃链中给定数量的元素。如果使用“通常”随机数生成器,则丢弃n数是O(n)运算。这意味着您无法并行化您的问题。你需要的是使用一个随机生成器,它包含一个方法来丢弃O(1)中的n个绘制。你可以在网上找到很多这样的方法。或者你可以自己编码(但这真的是试图重新发明轮子)。
我自己使用:https://rdrr.io/cran/sitmo/ 但是它适用于C ++,但是你可以确定你可以找到C版或者只使用C ++实现这一部分的版本......
以上是关于在MPI C中为每个进程生成随机数的主要内容,如果未能解决你的问题,请参考以下文章