4

我想知道为什么这个程序实际上可以在 MPI (openMPI 1.5/1.6.)

#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 类型数学规则,则两者都不应该完成。

4

1 回答 1

3

显然,在第二个程序中,rank 0 正在发送给自己,而 rank 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()状态,if 将返回MPI_UNDEFINED,因为从接收的原始整数元素的数量中无法构造整数数量的向量元素。混合原始类型也是不正确的,例如发送MPI_DOUBLE(或向量,或结构,或任何其他具有双精度的类型)并将其接收为MPI_INT.

Please also note that MPI messages do not carry their type map or type ID with them so most MPI implementations do not check if types match. It is possible to send MPI_FLOAT and receive it as MPI_INT (because both are 4 bytes on most systems) but it is not correct to do so.

于 2012-05-19T11:37:21.387 回答