:)
我有一个关于mpi程序的令人不安的问题。其思想是:每个进程(从进程)向主进程发送数据,以计算mandelbrot分形。
首先,每个从机发送点和it工作者。然后他们发了一条线,就成功了!
但现在,我试着让他们发送一个行块(假设5行,所以是一个子矩阵)。
我的想法是把这五行变成一行。主人收到了第一条“新”线路,但其他人没有收到。我很不安。
我为其他人收到(>1):
信号分割故障
信号代码:地址未映射
地址错误
请帮帮我!因为时间很长,我一直在寻找:(
我是法国人(所以我的英语不好)
//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的值不是数组第一项的地址!
因此,您能否尝试:

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);

如果要发送单个整数,该怎么办?&blockint a)的地址可以提供给a,这在许多专门讨论&a的示例中执行:
int a=42;
MPI_Send(&a,1, MPI_INT, 0, DATATAG, MPI_COMM_WORLD);

最后,确保调用MPI_Send()的次数与调用MPI_Send()的次数相同。实际上,在您发布的代码中,MPI_Send()只由根进程调用一次,而每个非根进程将向根进程发送一条消息。因此,程序将为两个进程工作,如果使用更多进程或使用单个进程,程序可能会失败。

10-02 14:33