我正在尝试生成随机数并将这些数字分配给每个任务中的数组。我想确保不同任务中的随机数不同。我该如何实现?
如果每个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();
}
答案 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 ++来编写此版本。