2012-05-19 50 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

对不起,我没有看到你问为什么它的作品时,类型不匹配。我已经扩大了答案。 –