并行编程:如何应用 'MPI_Gather' 或 'MPI_Scatter' 而不是 'MPI_Isend' 和 'MPI_Recv'
Parellel Programming: How can I apply 'MPI_Gather' or 'MPI_Scatter' instead of 'MPI_Isend' and 'MPI_Recv'
这是我计算素数的代码,我只想在这些进程之间使用集体通信。但是,当我使用 'MPI_Scatter' 和 'MPI_Gather' 而不是 MPI_Recv 和 MPI_Isend 更改代码时出现错误。我应该为它改变什么?
这是我的原始代码:
MPI_Request req;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if( my_rank == 0){
printf("Input(50-1000) : ");
fflush(stdout);
scanf("%d",&w);
for(i=0; i<w; i++) data[i] = i+1;
}
MPI_Bcast(&w, 1, MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(data, w, MPI_INT,0,MPI_COMM_WORLD);
if( my_rank != 0){
x = w/(p-1);
low = (my_rank-1)*x;
high = low+x-1;
for(num = data[low]; num <= data[high];num++){
result = 0;
t=1;
while(num>=t){
if(num%t==0)
result = result +1;
t += 1;
}
if(result==2) i += 1;
}
MPI_Isend(&i,1,MPI_INT,0,0,MPI_COMM_WORLD,&req);
}
if(my_rank == 0){
int j = 0;
for( j = 1; j < p; j++){
MPI_Recv(&i,1,MPI_DOUBLE,MPI_ANY_SOURCE,0,MPI_COMM_WORLD,&status);
printf("Process %d : There are %d prime numbers\n",status.MPI_SOURCE,i );
}
}
MPI_Finalize();
}
输出为:
Input(50-1000) : 50
Process 1 : There are 5 prime numbers
Process 2 : There are 4 prime numbers
Process 3 : There are 2 prime numbers
Process 4 : There are 4 prime numbers
这是我更改代码的部分:
if( my_rank != 0){
x = w/(p-1);
low = (my_rank-1)*x;
high = low+x-1;
for(num = data_send[low]; num <= data[high];num++){
result = 0;
t=1;
while(num>=t){
if(num%t==0)
result = result +1;
t += 1;
}
if(result==2) i += 1;
}
MPI_Scatter(data_send,1,MPI_INT,data_recv,1,MPI_INT,0,MPI_COMM_WORLD);
}
MPI_Scatter
是集体行动,需要全军衔接。 MPI_Gather
.
也是如此
这意味着:MPI_Scatter
调用应该移到代码中的 if
块之外(对于 MPI_Gather
也是如此)。
你可以找到一个例子here。
这里是你如何使用MPI_Gather()
int * results;
if( my_rank != 0){
x = w/(p-1);
low = (my_rank-1)*x;
high = low+x-1;
for(num = data[low]; num <= data[high];num++){
result = 0;
t=1;
while(num>=t){
if(num%t==0)
result = result +1;
t += 1;
}
if(result==2) i += 1;
}
} else {
results = (int *)malloc(p * sizeof(int));
}
MPI_Gather(&i, 1, MPI_INT, results, 1, MPI_INT, 0, MPI_COMM_WORLD);
if(my_rank == 0){
int j = 0;
for( j = 1; j < p; j++){
printf("Process %d : There are %d prime numbers\n",j, results[j]);
}
free(results);
}
请注意,您可以安排此算法以便也对等级 0 进行计算,因此使用 p
MPI 任务而不是 p-1
这是我计算素数的代码,我只想在这些进程之间使用集体通信。但是,当我使用 'MPI_Scatter' 和 'MPI_Gather' 而不是 MPI_Recv 和 MPI_Isend 更改代码时出现错误。我应该为它改变什么?
这是我的原始代码:
MPI_Request req;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if( my_rank == 0){
printf("Input(50-1000) : ");
fflush(stdout);
scanf("%d",&w);
for(i=0; i<w; i++) data[i] = i+1;
}
MPI_Bcast(&w, 1, MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(data, w, MPI_INT,0,MPI_COMM_WORLD);
if( my_rank != 0){
x = w/(p-1);
low = (my_rank-1)*x;
high = low+x-1;
for(num = data[low]; num <= data[high];num++){
result = 0;
t=1;
while(num>=t){
if(num%t==0)
result = result +1;
t += 1;
}
if(result==2) i += 1;
}
MPI_Isend(&i,1,MPI_INT,0,0,MPI_COMM_WORLD,&req);
}
if(my_rank == 0){
int j = 0;
for( j = 1; j < p; j++){
MPI_Recv(&i,1,MPI_DOUBLE,MPI_ANY_SOURCE,0,MPI_COMM_WORLD,&status);
printf("Process %d : There are %d prime numbers\n",status.MPI_SOURCE,i );
}
}
MPI_Finalize();
}
输出为:
Input(50-1000) : 50
Process 1 : There are 5 prime numbers
Process 2 : There are 4 prime numbers
Process 3 : There are 2 prime numbers
Process 4 : There are 4 prime numbers
这是我更改代码的部分:
if( my_rank != 0){
x = w/(p-1);
low = (my_rank-1)*x;
high = low+x-1;
for(num = data_send[low]; num <= data[high];num++){
result = 0;
t=1;
while(num>=t){
if(num%t==0)
result = result +1;
t += 1;
}
if(result==2) i += 1;
}
MPI_Scatter(data_send,1,MPI_INT,data_recv,1,MPI_INT,0,MPI_COMM_WORLD);
}
MPI_Scatter
是集体行动,需要全军衔接。 MPI_Gather
.
这意味着:MPI_Scatter
调用应该移到代码中的 if
块之外(对于 MPI_Gather
也是如此)。
你可以找到一个例子here。
这里是你如何使用MPI_Gather()
int * results;
if( my_rank != 0){
x = w/(p-1);
low = (my_rank-1)*x;
high = low+x-1;
for(num = data[low]; num <= data[high];num++){
result = 0;
t=1;
while(num>=t){
if(num%t==0)
result = result +1;
t += 1;
}
if(result==2) i += 1;
}
} else {
results = (int *)malloc(p * sizeof(int));
}
MPI_Gather(&i, 1, MPI_INT, results, 1, MPI_INT, 0, MPI_COMM_WORLD);
if(my_rank == 0){
int j = 0;
for( j = 1; j < p; j++){
printf("Process %d : There are %d prime numbers\n",j, results[j]);
}
free(results);
}
请注意,您可以安排此算法以便也对等级 0 进行计算,因此使用 p
MPI 任务而不是 p-1