2017-10-11 85 views
0

这是我计算素数的代码,我只想在这些过程中使用集体通信。但是,当我使用'MPI_Scatter'和'MPI_Gather'而不是MPI_Recv和MPI_Isend更改我的代码时,出现错误。我应该改变什么?Parellel编程:我如何申请'MPI_Gather'或'MPI_Scatter'而不是'MPI_Isend'和'MPI_Recv'

这是我的原代码:

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); 
    } 
+0

什么错误没有你得到 – cowbert

+0

它只显示'输入(50-1000):'输入问题,似乎程序继续运行而不提供结果 – Lumby

+0

请注意您发送'MPI_INT',但收到'MPI_DOUBLE'。而且你也不会'MPI_Wait()''MPI_Isend()'返回的请求' –

回答

1

这里是你如何使用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

+0

哦,我知道了!非常感谢你 :) – Lumby

1

MPI_Scatter是一项集体行动,需要被所有级别召集。 MPI_Gather也是如此。

这意味着:MPI_Scatter呼叫应该移出代码中的if块之外(对于MPI_Gather也是如此)。

您可以找到一个示例here

+0

另外,根据MPI_Send()'''MPI_Recv()'版本,你需要'MPI_Gather()'而不是'MPI_Scatter() '。 –

+0

btw,你可能会考虑在等级0上做一些计算,否则,会浪费等待'MPI_Gather()'完成的资源。 –

+0

你能更准确地解释我吗?当我把MPI_Gather函数放在if块之外时,所有的数据都没有了......所有进程都是0,所有素数也是原始输入值 – Lumby