MPI发送/接收数百万条消息

MPI发送/接收数百万条消息,mpi,Mpi,对于大于0的进程,我有一个NT循环(数百万次迭代)。对于每次迭代,120字节的消息被发送到proc0,proc0接收它们(对于proc0,我在NT上有相同的循环) 我希望proc 0接收订购的数据,以便将它们存储在数组nhdr1中 问题是proc0不能正确地接收消息,我在数组nhdr中经常有0个值 如何修改代码,使消息的接收顺序与发送顺序相同 [...] if (rank == 0) { nhdr = malloc((unsigned long)15*sizeof(*

对于大于0的进程,我有一个NT循环(数百万次迭代)。对于每次迭代,120字节的消息被发送到proc0,proc0接收它们(对于proc0,我在NT上有相同的循环)

我希望proc 0接收订购的数据,以便将它们存储在数组nhdr1中

问题是proc0不能正确地接收消息,我在数组nhdr中经常有0个值

如何修改代码,使消息的接收顺序与发送顺序相同

[...]
    if (rank == 0) {

        nhdr  = malloc((unsigned long)15*sizeof(*nhdr));
        nhdr1 = malloc((unsigned long)NN*15*sizeof(*nhdr1));

        itr = 0;
        jnode = 1;

        for (l=0; l<NT; l++) {

            MPI_Recv(nhdr, 15, MPI_LONG, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

            if (l == status.MPI_TAG) {
                for (i=0; i<nkeys; i++)
                    nhdr1[itr*15+i] = nhdr[i];
            }

            itr++;

            if (itr == NN) {
                ipos = (unsigned long)(jnode-1)*NN*15*sizeof(*nhdr1);

                fseek(ismfh, ipos, SEEK_SET);
                nwrite += fwrite(nhdr1, sizeof(*nhdr1), NN*15, ismfh);

                itr = 0;
                jnode++;
            }
        }

        free(nhdr);
        free(nhdr1);

    } else {

        nhdr = malloc(15*sizeof(*nhdr));

        irecmin = (rank-1)*NN+1;
        irecmax = rank*NN;

        for (l=0; l<NT; l++) {
            if (jrec[l] >= irecmin && jrec[l] <= irecmax) {

                indx1 = (unsigned long)(jrec[l]-irecmin) * 15;

                for (i=0; i<15; i++)
                    nhdr[i] = nhdr1[indx1+i]; // nhdr1 is allocated before for rank>0!

                MPI_Send(nhdr, 15, MPI_LONG, 0, l, MPI_COMM_WORLD);
            }
        }

        free(nhdr);

    }
[…]
如果(秩==0){
nhdr=malloc((无符号长)15*sizeof(*nhdr));
nhdr1=malloc((无符号长)NN*15*sizeof(*nhdr1));
itr=0;
jnode=1;

对于(l=0;l无法保证您的消息将以从不同级别发送的相同顺序到达级别0。例如,如果您有这样的场景(
S1
表示发送消息1):

无法保证消息将以S1、S2、S3、S4的顺序到达秩0。MPI提供的唯一保证是,在具有相同标记(您正在执行)的同一通信器上发送的每个秩的消息将以其发送的相同顺序到达。这意味着产生的顺序可能是:

S1, S2, S3, S4
S1, S3, S2, S4
或者可以是:

S1, S2, S3, S4
S1, S3, S2, S4
或:

……等等


对于大多数应用程序来说,这并不重要。重要的顺序是逻辑顺序,而不是实时顺序。您可以再看一看应用程序,确保您的要求不会有丝毫的放松。

无法保证您的消息将以与发送时相同的顺序到达0级来自不同级别。例如,如果您有这样的场景(
S1
表示发送消息1):

无法保证消息将以S1、S2、S3、S4的顺序到达秩0。MPI提供的唯一保证是,在具有相同标记(您正在执行)的同一通信器上发送的每个秩的消息将以其发送的相同顺序到达。这意味着产生的顺序可能是:

S1, S2, S3, S4
S1, S3, S2, S4
或者可以是:

S1, S2, S3, S4
S1, S3, S2, S4
或:

……等等

对于大多数应用程序来说,这并不重要。重要的顺序是逻辑顺序,而不是实时顺序。您可以再看一看您的应用程序,确保您的要求不会有丝毫的放松。

您所说的“消息接收的顺序与发送的顺序相同”是什么意思

在现在的代码中,消息的接收顺序(大致)与它们实际发送的顺序相同……但该顺序与排名数字无关,或者与其他任何事情无关。有关更多信息,请参阅@Wesley Bland的回复

如果您的意思是“按排名顺序接收消息”…那么有几个选项

首先,像MPI_Gather或MPI_Gatherv这样的集合将是一个“明显”的选择,以确保数据按产生数据的列组排序。这仅在每个列组进行相同次数的迭代,并且这些迭代保持大致同步时才有效

其次,您可以删除任何源的MPI\u,并发布一组MPI\u IRevc,其中缓冲区按“顺序”提供。当消息到达时,它将“自动”位于正确的缓冲区位置对于接收到的每条消息,可以使用提供的正确recv缓冲区位置发布新的MPI_Irecv。任何不匹配的MPI_Irecv都需要在作业结束时取消。

您所说的“消息接收顺序与发送顺序相同”是什么意思

在现在的代码中,消息的接收顺序(大致)与它们实际发送的顺序相同……但该顺序与排名数字无关,或者与其他任何事情无关。有关更多信息,请参阅@Wesley Bland的回复

如果您的意思是“按排名顺序接收消息”…那么有几个选项

首先,像MPI_Gather或MPI_Gatherv这样的集合将是一个“明显”的选择,以确保数据按产生数据的列组排序。这仅在每个列组进行相同次数的迭代,并且这些迭代保持大致同步时才有效

其次,您可以删除任何源的MPI\u,并发布一组MPI\u IRevc,其中缓冲区按“顺序”提供。当消息到达时,它将“自动”位于正确的缓冲区位置对于接收到的每条消息,可以使用提供的正确recv缓冲区位置发布新的MPI\u Irecv。任何不匹配的MPI\u Irecv都需要在作业结束时取消。

请记住:

  • 按顺序和顺序接收来自给定列组的消息
  • 消息在MPI_Recv()返回的状态结构()中具有原始处理器秩
您可以使用这两个元素将接收到的数据正确地放入nhdr1。

请记住:

  • 按顺序和顺序接收来自给定列组的消息
  • 消息在MPI_Recv()返回的状态结构()中具有原始处理器秩
您可以使用这两个元素将接收到的数据正确地放入nhdr1中