:)
我遇到了一个关于 mpi 程序的令人不安的问题。这个想法是:每个进程(slave)发送数据给 master 来计算 mandelbrot 分形。
首先,每个slave发送point和它的worker。然后他们发送了线路,它成功了!
但是现在,我试着让他们发送一行代码(假设有 5 行代码,所以是一个子矩阵)。
我的想法是把这五行变成一行。主人收到第一条"new"线但没有收到其他的O_o。我很不安。
我为其他人接收(>1) : 信号分割故障 信号代码:地址未映射 地址失败
请帮帮我!因为好久了,一直在找:(
Ps : 我是法国人(所以这就是我英语不好的原因)
//the whole table to be used in a master
//int table[NX*NY];
//int count =0;
if (rank == 0) {
int res;
int line[MAXY+MAXY+1];
int block[5*(MAXY+MAXY+1)];
int count = 0;
/* Begin User Program - the master */
//MPI_Recv(&line, MAXY+MAXY+1, MPI_INT,MPI_ANY_SOURCE, DATATAG, MPI_COMM_WORLD, &status);
MPI_Recv(&block, 5*(MAXY+MAXY+1), MPI_INT,MPI_ANY_SOURCE, DATATAG, MPI_COMM_WORLD, &status);
printf("sizeof of datablock received is = %d \n",sizeof(block)/sizeof(block[0]));
recvd = status.MPI_SOURCE;
printf("i have received blockdata from %d \n",recvd);
/* remplissage du case */
for(i = -MAXX; i <= MAXX; i++) {
for(j = -MAXY; j <= MAXY; j++) {
cases[i + MAXX][j + MAXY] = block[count%(MAXY+MAXY+1)];
//printf("j'ai fait un bloc[count], pas credible\n");
count++;
}
}
dump_ppm("mandel.ppm", cases);
printf("Fini.\n");
}
else {
/* On est l'un des fils */
/* for the block;let's suppose each son send 5 rows*/
double x, y;
int i, j, res, rc, rank,count;
//int line[MAXY + MAXY + 1];
int block[5*(MAXY+MAXY+1)];
count = 0;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
for(i = -MAXX; i <= MAXX; i++) {
for(j = -MAXY; j <= MAXY; j++) {
x = 2 * i / (double)MAXX;
y = 1.5 * j / (double)MAXY;
res = mandel(x, y);
//line[j+MAXY] = res;
block[count] =res;
if (count % (5*(MAXY+MAXY+1)) == 0){ //we send each five rows
MPI_Send(&block,5*(MAXY+MAXY+1), MPI_INT, 0, DATATAG, MPI_COMM_WORLD);
printf("me slave %d, have sent datablock to master\n",rank);
printf("sizeof of datablock sent is = %d\n",sizeof(block)/sizeof(block[0]));
}
count++;
}
//MPI_Send(&line, MAXY+MAXY+1 , MPI_INT, 0, DATATAG, MPI_COMM_WORLD);
}
}
MPI_Finalize();
return 0;
}
最佳答案
函数MPI_Recv()
需要接收数据的缓冲区地址。 MPI_Send()
也是一样。由于int block[5*(MAXY+MAXY+1)]
是一个数组,block
指向数组的第一项block[0]
:这是所需的地址。另一方面,&block
指向block
:它类似于指向int
的指针。但是&block
的值并不是数组第一项的地址!
因此,你可以尝试:
int block[5*(MAXY+MAXY+1)]
...
MPI_Send(block,5*(MAXY+MAXY+1), MPI_INT, 0, DATATAG, MPI_COMM_WORLD);
...
MPI_Recv(block, 5*(MAXY+MAXY+1), MPI_INT,MPI_ANY_SOURCE, DATATAG, MPI_COMM_WORLD, &status);
相当于:
int block[5*(MAXY+MAXY+1)]
...
MPI_Send(&block[0],5*(MAXY+MAXY+1), MPI_INT, 0, DATATAG, MPI_COMM_WORLD);
...
MPI_Recv(&block[0], 5*(MAXY+MAXY+1), MPI_INT,MPI_ANY_SOURCE, DATATAG, MPI_COMM_WORLD, &status);
如果你发送一个整数 int a
会怎么样? a
(&a
) 的地址可以提供给 MPI_Send()
,正如在许多致力于 MPI_Send()< 的示例中所执行的那样
:
int a=42;
MPI_Send(&a,1, MPI_INT, 0, DATATAG, MPI_COMM_WORLD);
最后,确保 MPI_Send()
的调用次数与 MPI_Recv()
的调用次数相同。实际上,在您发布的代码中,MPI_Recv()
仅被根进程调用一次,而每个非根进程都会向根进程发送一条消息。因此,该程序将适用于 2 个进程,如果使用更多进程或使用单个进程,它可能会失败。
关于c - 尝试使用 Mpi recv : signal segmentation fault 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40196900/