pointers - 如何用MPI发送和接收 1D array的边界数据?

  显示原文与译文双语对照的内容
0 0

晚安
我正在尝试修复这个MPI代码的问题。

主服务器可以发送 1D array 块,但是当工人与邻居交换数据时,程序就会认为这是因为我应该创建一个向量数据类型,而第一个元素才可以发送?

这是给我带来问题的代码的一部分:

numworkers = numtasks-1;
if (taskid == MASTER) {
 printf("Mastern");
double *Q=malloc(m * n * cell_size * sizeof(double));
/*Set initial Gauss hump*/
for (k=0;k<3;k++) 
for (i = 0; i <m; i++) {
 for (j = 0; j <n; j++) {
 Q(k,i,j) = 4.0;
 }
 }
 printf("gauss done.n");
 averow = (m*n*cell_size)/numworkers;
 extra = (m*n*cell_size)%numworkers;
 MPI_Type_contiguous(rows, MPI_DOUBLE, &rowtype);!
 MPI_Type_commit(&rowtype);
 printf ("Starting program with %d worker tasks.n", numworkers);
 printf("Grid size: X= %d Y= %d Time steps= %dn",m,n,STEPS);
 for (i=1; i<=numworkers; i++)//Distribute work to workers.
 {rows = (i <= extra)? averow+1 : averow; 
 if (i == 1)//neighbors
 left = NONE;
 else
 left = i - 1;
 if (i == numworkers)
 right = NONE;
 else
 right = i + 1;
/* Now send startup information to each worker */
 dest = i;
 MPI_Send(&rows, 1, MPI_INT, dest, BEGIN, MPI_COMM_WORLD);
 MPI_Send(&left, 1, MPI_INT, dest, BEGIN, MPI_COMM_WORLD);
 MPI_Send(&right, 1, MPI_INT, dest, BEGIN, MPI_COMM_WORLD);
 MPI_Send(Q,1, rowtype, dest, BEGIN, 
 MPI_COMM_WORLD);
 printf("Sent to task %d: rows= %d offset= %d",dest,rows,offset);
 printf("left= %d right= %dn",left,right);
 offset = offset + rows;
 }
 for (i=1; i<=numworkers; i++)
 {
 source = i;
 msgtype = DONE;
 MPI_Irecv(&rows, 1, MPI_INT, source, msgtype, MPI_COMM_WORLD, &request); 
 MPI_Irecv(Q, 1,rowtype, source,
 msgtype, MPI_COMM_WORLD, &request);
 }
 printf("Solver tookn");
 free(Q);
 MPI_Type_free(&rowtype);
 MPI_Finalize();}
 if (taskid!= MASTER) 
 {MPI_Recv(&rows, 1, MPI_INT, MASTER, BEGIN, MPI_COMM_WORLD, &status);
 double *Q =malloc(rows* sizeof(double)); 
 MPI_Recv(&left, 1, MPI_INT, MASTER, BEGIN, MPI_COMM_WORLD, &status);
 MPI_Recv(&right, 1, MPI_INT, MASTER, BEGIN, MPI_COMM_WORLD, &status);
 MPI_Recv(Q, rows, MPI_DOUBLE, MASTER, BEGIN, MPI_COMM_WORLD, &status);
 printf("ricevo da master rows %d n",rows); 
 printf("Task %d received work. Beginning time steps...n",taskid);
 for (it = 1; it <= numworkers; it++)
 {{if (left!= NONE)//boundary data exchange
 {MPI_Send(Q, 1, MPI_DOUBLE, left,
 RTAG, MPI_COMM_WORLD);
 source = left;
 msgtype = LTAG;
 MPI_Recv(Q, 1, MPI_DOUBLE, source,
 msgtype, MPI_COMM_WORLD, &status);}
 if (right!= NONE)
 {
 MPI_Send(Q, 1, MPI_DOUBLE, right,
 LTAG, MPI_COMM_WORLD);
 source = right;
 msgtype = RTAG;
 MPI_Recv(Q, 1, MPI_DOUBLE, source, msgtype,
 MPI_COMM_WORLD, &status);}
/* Now call update to update the value of grid points*/
 Q=Q+1;
 printf("update fatto."); }
/* Finally, send my portion of final results back to master */
 MPI_Send(&offset, 1, MPI_INT, MASTER, DONE, MPI_COMM_WORLD);
 MPI_Send(&rows, 1, MPI_INT, MASTER, DONE, MPI_COMM_WORLD);
 MPI_Send(Q, rows, MPI_DOUBLE, MASTER, DONE, 
 MPI_COMM_WORLD);
 free(Q); 
 MPI_Type_free(&rowtype); 
 MPI_Finalize();
 }

Q 被定义为:

 #define Q(i,j,k) Q[((k) + n * ((j) + m * (i)))]

调试:我正在使用 Putty的大学服务器。 如何调试这里程序?

太感谢你了,希望有人能帮助我 !

时间:原作者:4个回答

0 0

我尝试使用非阻塞,现在它可以工作。 由于任务没有接收和发送数据在右边的way.I 更改了数据的大小,它是另一个 Bug 。

if (left!= NONE)//boundary data exchange
 {MPI_Send(Q, 1, MPI_DOUBLE, left,
 RTAG, MPI_COMM_WORLD);
 source = left;
 msgtype = LTAG;
 MPI_Recv(Q, 1, MPI_DOUBLE, source,
 msgtype, MPI_COMM_WORLD, &status);}
 if (right!= NONE)
 {
 MPI_Send(Q, 1, MPI_DOUBLE, right,
 LTAG, MPI_COMM_WORLD);
 source = right;
 msgtype = RTAG;
 MPI_Recv(Q, 1, MPI_DOUBLE, source, msgtype,
 MPI_COMM_WORLD, &status);}

我使用了:

if (left!= NONE)//boundary data exchange
 {MPI_Isend(Q, rows, MPI_DOUBLE, left,
 RTAG, MPI_COMM_WORLD,&req1);
 source = left;
 msgtype = LTAG;
 MPI_Irecv(Q, rows, MPI_DOUBLE, source,
 msgtype, MPI_COMM_WORLD, &req2);
 printf("boundary left done");
 MPI_Wait(&req1,&status);
 MPI_Wait(&req2,&status);
 }
 if (right!= NONE)
 {
 MPI_Isend(Q, rows, MPI_DOUBLE, right,
 LTAG, MPI_COMM_WORLD,&req3);
 source = right;
 msgtype = RTAG;
 MPI_Irecv(Q, rows, MPI_DOUBLE, source, msgtype,
 MPI_COMM_WORLD, &req4);
 printf("boundary right done");
 MPI_Wait(&req3,&status);
 MPI_Wait(&req4,&status);}

感谢你的帮助 !

原作者:
...