2017-10-11 141 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