由于某种原因,我的其他进程没有收到第一个进程的数据(C中的​​MPI)

时间:2017-01-23 23:09:17

标签: c mpi

我要做的是创建一个1和0的数组,并将整个数组拆分为4个进程(不管我的测试用例有多少4个)并让每个进程打印其等级,长度为数组和数组本身。但是当我运行代码时,我会得到类似的结果:

Enter length and sequence length
100 4
1101000010110110101110101
1110101001111100011100100
1011100110011100001011010
1000110101001000001000111

Rank: 0   Length: 25

我不确定为什么会这样。出于某种原因,我无法将数据正确地传递给其他进程(我对MPI来说很新)

这是我的代码:

#include "ore_header.h"

int main(int argc, char** argv) {

srand(time(NULL));

    int     my_rank, p;
    int     total;
    int     length;
    int     seq_length;
    void    generate_sequence(int *arr, int n);
    int     subsequence_check(int *arr,int n, int m);


    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &p);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

    MPI_Request     reqs[p];
    MPI_Status      stats[p];
    int     p_length;
    int     p_total[p];
    int     *buf[p];
    if (my_rank == 0) {
        printf("Enter length and sequence length\n");
        scanf("%d %d",&length, &seq_length);
        p_length = length / p;
        for (int i = 0; i < p; i++) {
            buf[i] = (int*)malloc(p_length*sizeof(int));
            generate_sequence(buf[i], p_length); //Generates a sequence
            MPI_Isend(&buf[i], p_length, MPI_INT, i, 0, MPI_COMM_WORLD, &reqs[i]); //Send each buffer to each sequence
            MPI_Wait(&reqs[my_rank], &stats[my_rank]); //Wait for data to be sent
        }
    }
    MPI_Irecv(&buf[my_rank], p_length, MPI_INT, 0, 0, MPI_COMM_WORLD, &reqs[my_rank]); //Receive Data from process 0
    MPI_Wait(&reqs[my_rank], &stats[my_rank]); //Wait for communication to end
    printf("\nRank: %d   Length: %d\n",my_rank,p_length);
    for (int i = 0; i < p_length; i++) {
        printf("%d",buf[i]);
    }

    //tot = subsequence_check(buf,length,seq_length);
    //printf("\n\nTotal: %d\n",tot);
    MPI_Finalize();
    return (0);
}

更新

感谢您提供反馈,我已经修复了问题,现在它按预期工作了:

#include "ore_header.h"

int main(int argc, char** argv) {

    srand(time(NULL));

    int     my_rank, p;
    int     total;
    int     length;
    int     flag;
    int     seq_length;
    void    generate_sequence(int *arr, int n);
    int     subsequence_check(int *arr,int n, int m);


    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &p);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);


    int     p_length;
    int     *buf[p];
    if (my_rank == 0) {
        printf("Enter length and sequence length\n");
        scanf("%d %d",&length, &seq_length);
        p_length = length / p;
        for (int i = 0; i < p; i++) {
            buf[i] = (int*)malloc(p_length*sizeof(int));
            generate_sequence(buf[i], p_length);
            MPI_Send(buf[i], p_length, MPI_INT, i, 0, MPI_COMM_WORLD);
            printf("Data sent to process %d\n", i);
        }
    }
    MPI_Bcast(&p_length, 1, MPI_INT, 0, MPI_COMM_WORLD);
    buf[my_rank] = (int*)malloc(p_length*sizeof(int));
    MPI_Status      stats[p];
    MPI_Request     reqs[p];
    MPI_Irecv(buf[my_rank], p_length, MPI_INT, 0, 0, MPI_COMM_WORLD, &reqs[my_rank]);
    while(1) {
        MPI_Test(&reqs[my_rank], &flag, &stats[my_rank]);
        if (flag) break;
    }
    printf("\nData received on process: %d   Length: %d\n",my_rank,p_length);
    for (int i = 0; i < p_length; i++) {
        printf("%d",buf[my_rank][i]);
    }
    printf("\n");

    //tot = subsequence_check(buf,length,seq_length);
    //printf("\n\nTotal: %d\n",tot);
    MPI_Finalize();
    return (0);
}

这是我的输出:

Enter length and sequence length
100 4
0101100011001110110010011
Data sent to process 0
0010011010000001001010111
Data sent to process 1
0011111111101101100000111
Data sent to process 2
0000000100010011100001111
Data sent to process 3

Data received on process: 0   Length: 25
0101100011001110110010011

Data received on process: 1   Length: 25
0010011010000001001010111

Data received on process: 2   Length: 25
0011111111101101100000111

Data received on process: 3   Length: 25
0000000100010011100001111

1 个答案:

答案 0 :(得分:0)

MPI_Isend()需要指向缓冲区的指针,&buf[i]是指向缓冲区的指针。因此,您可以尝试MPI_Isend(buf[i],...吗?

此外,请求reqs[i]MPI_Isend()中设置,但MPI_Wait()仅检查reqs[my_rank]的完成情况。因此,可以建议另一种修改:

MPI_Isend(buf[i], p_length, MPI_INT, i, 0, MPI_COMM_WORLD, &reqs[i]); //Send each buffer to each sequence
MPI_Wait(&reqs[i], &stats[i]); //Wait for data to be sent

MPI_Wait()之后调用MPI_Isend()似乎等同于调用MPI_Send(),特别是如果返回的MPI_Status未经MPI_Test_cancelled()之类的测试。在目前的情况下,对MPI_Wait()的连续调用很容易被for循环结束时对MPI_Waitall()的单个调用所取代。

编辑:关于0以外的等级p_lengthMPI_Irecv()的值@ a3f的问题仍然有效...