2012-05-19 51 views
4

我在想,爲什麼這個節目在MPI實際工作(的openmpi 1.5/1.6)。MPI類型匹配

#include <stdio.h> 
#include <mpi.h> 

#define VECTOR_SIZE 100 

int main(int argc,char ** argv) { 
    int A[VECTOR_SIZE]; 
    int sub_size=2; 
    int count=10; 
    MPI_Datatype partial_array; 
    int rank,size; 
    MPI_Status status; 

    MPI_Init(&argc,&argv); 
    MPI_Comm_rank(MPI_COMM_WORLD,&rank); 
    MPI_Comm_size(MPI_COMM_WORLD,&size); 

    MPI_Type_vector(count, sub_size, 
      2*sub_size, MPI_INT, &partial_array); 

    MPI_Type_commit(&partial_array); 

    if (rank == 0) { 
    int i; 
    // server - initialize data and send 
    for (i = 0; i< VECTOR_SIZE; i++) { 
     A[i] = i; 
    } 
    MPI_Send(&(A[0]), 1, partial_array, 1, 0, MPI_COMM_WORLD); 
    } else if (rank==1) { 
    int i; 
    for (i = 0; i< VECTOR_SIZE; i++) { 

     A[i] = 0; 

    } 
    // vector is composed by 20 MPI_INT elements 
    MPI_Recv(&(A[0]),20, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); 

    printf("\n"); 

    for (i = 0; i<VECTOR_SIZE; i++) { 
     printf("%d ",A[i]); 

    } 
    printf("\n"); 
    } 

    MPI_Finalize(); 

} 

,而其中發送和接收原語交換這個其他程序不終止(接收從未完成) :

#include <stdio.h> 
#include <mpi.h> 

#define VECTOR_SIZE 100 

int main(int argc,char ** argv) { 
    int A[VECTOR_SIZE]; 
    int sub_size=2; 
    int count=10; 
    MPI_Datatype partial_array; 
    int rank,size; 
    MPI_Status status; 

    MPI_Init(&argc,&argv); 
    MPI_Comm_rank(MPI_COMM_WORLD,&rank); 
    MPI_Comm_size(MPI_COMM_WORLD,&size); 

    MPI_Type_vector(count, sub_size, 
        2*sub_size, MPI_INT, &partial_array); 

    MPI_Type_commit(&partial_array); 

    if (rank == 0) { 
     int i; 
     // server - initialize data and send 
     for (i = 0; i< VECTOR_SIZE; i++) { 

      A[i] = i; 

     } 
     MPI_Send(&(A[0]),20, MPI_INT, 0, 0, MPI_COMM_WORLD); 

    } else if (rank==1) { 
     int i; 
     // client - receive data and print 
     for (i = 0; i< VECTOR_SIZE; i++) { 

      A[i] = 0; 

     } 

     MPI_Recv(&(A[0]), 1, partial_array, 1, 0, MPI_COMM_WORLD, &status); 

     printf("\n"); 

     for (i = 0; i<VECTOR_SIZE; i++) { 
      printf("%d ",A[i]); 

     } 
     printf("\n"); 
    } 

    MPI_Finalize(); 

} 

如果我沒有理解MPI型mathing規則正確二者既不應該完成。

在第二程序秩

回答

3

顯然0被髮送到其自身和秩1從本身也期待消息:

MPI_Send(&(A[0]),20, MPI_INT, 0, 0, MPI_COMM_WORLD); 

目的地等級應爲1,而不是0

MPI_Recv(&(A[0]), 1, partial_array, 1, 0, MPI_COMM_WORLD, &status); 

源秩應是0,而不是1.

否則你不明白MPI類型匹配是否正確。它只說明兩端的類型圖中的基礎原始類型應該匹配。您正在創建一個矢量,其類型圖有20個基本整數。如果你發送一個這種類型的元素,你的消息實際上將包含20個整數。在接收端,您至少爲20個整數提供空間,所以這是正確的。相反也是正確的。

如果在第二個程序只發送10或18的整數,因爲它們不會使矢量型完整元素,它是不正確的。儘管如此,接收操作將完成,但如果您在狀態上調用MPI_Get_count(),如果將返回MPI_UNDEFINED,因爲從接收到的基本整數元素的數量,不能構建整數個向量元素。混合原始類型也是不正確的,例如,發送MPI_DOUBLE(或矢量,或結構,或任何其他類型的雙打),並將其作爲MPI_INT接收。

請注意,MPI消息不會攜帶它們的類型映射或類型ID,因此大多數MPI實現不檢查類型是否匹配。它是可能發送MPI_FLOAT並接收它作爲MPI_INT(因爲都在大多數系統上是4個字節),但它不是正確這樣做。

+0

好的,那是一個愚蠢的錯誤。但是,爲什麼這個工作?發送和接收MPI_datatypes不匹配。 – igon

+1

@igon:發送端和接收端的數據類型不需要完全匹配。只有數據的類型和數量很重要。發送進程可以使用任何類型映射將10個整數打包在一起,並且接收進程可以使用由10個整數組成的任何類型映射來接收該消息。 – suszterpatt

+0

對不起,我沒有看到你問爲什麼它的作品時,類型不匹配。我已經擴大了答案。 –