MPI - 发送数组的段

时间:2013-03-18 17:43:10

标签: arrays mpi send stride

所以我有一系列双打。我想每隔5小时发送一次接收过程。基本上,我需要一种在它们之间发送特定双打的方法。除了将双打存储到发送缓冲区之外,还有一个功能吗?制作我自己的派生类型会更好吗?

1 个答案:

答案 0 :(得分:7)

你绝对应该创建一个MPI数据类型;它为MPI库提供了避免从数组中编组的额外副本的机会,并且在这种情况下使用MPI_Type_vector()非常简单:

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

int main(int argc, char** argv)
{
    int size, rank;
    const int bigsize=50;
    const int stride = 5;
    const int count = (bigsize + stride - 1)/stride;

    const int sender = 0;
    const int receiver = 1;
    const int mytag = 1;

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

    if (size < 2) {
        fprintf(stderr,"%s: Require at least two processors.\n", argv[0]);
        MPI_Finalize();
        exit(-1);
    }


    if(rank == sender)
    {
        double bigarray[bigsize];
        for (int i=0; i<bigsize; i++)
            bigarray[i] = 0.;

        for (int i=0; i<bigsize; i+=stride)
            bigarray[i] = i/stride;

        printf("[%d]: ", rank);
        for (int i=0; i<bigsize; i++)
            printf("%lf ", bigarray[i]);
        printf("\n");

        MPI_Datatype everyfifth;

        MPI_Type_vector( count, 1, stride, MPI_DOUBLE, &everyfifth);
        MPI_Type_commit(&everyfifth);

        MPI_Send(bigarray, 1, everyfifth, receiver, mytag, MPI_COMM_WORLD);

        MPI_Type_free(&everyfifth);
    }
    else if( rank == receiver )
    {
        double littlearray[count];

        MPI_Status status;

        MPI_Recv(littlearray, count, MPI_DOUBLE, sender, mytag,
                    MPI_COMM_WORLD, &status);

        printf("[%d]: ", rank);
        for (int i=0; i<count; i++)
            printf("%lf ", littlearray[i]);
        printf("\n");
    }

    MPI_Finalize();

    return 0;
}

编译并运行

$ mpicc -o vector vector.c -std=c99
$ mpirun -np 2 ./vector
[0]: 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000 2.000000 0.000000 0.000000 0.000000 0.000000 3.000000 0.000000 0.000000 0.000000 0.000000 4.000000 0.000000 0.000000 0.000000 0.000000 5.000000 0.000000 0.000000 0.000000 0.000000 6.000000 0.000000 0.000000 0.000000 0.000000 7.000000 0.000000 0.000000 0.000000 0.000000 8.000000 0.000000 0.000000 0.000000 0.000000 9.000000 0.000000 0.000000 0.000000 0.000000 
[1]: 0.000000 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000 9.000000