为什么我的C ++并行程序在MPI_Gather中给出MPI致命错误?

维克多·迪米特里奥斯基(Viktor Dimitrioski)

我的排序程序可以在数组中偶数个元素上正常工作,但是会出现错误

MPI_Gather中的致命错误:消息被截断,错误堆栈:MPI_Gather(sbuf = 0x00A2A700,scount = 4,MPI_INT,rbuf = 0x00A302C8,rcount = 4,MPI_INT,root = 0,MPI_COMM_WORLD)失败,来自等级1和标记-1342177184 ;接收到28个字节,但缓冲区大小为16

对于数组中元素的奇数个。问题始于代码if ((world_rank == 1) && (n % world_size != 0))我尝试了一切,但没有成功。我怎样才能解决这个问题?提前致谢!

void merge(int*, int*, int, int, int);
void mergeSort(int*, int*, int, int);

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

    


    int world_rank;
    int world_size;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    int n = atoi(argv[1]);
    int* original_array{ new int[n] {} };
    //int original_array[]=new int[n];

    int c;
    srand(time(NULL));

    if (world_rank == 0) {
        printf("This is the unsorted array: ");
        for (c = 0; c < n; c++) {

        original_array[c] = rand() % n;
        printf("%d ", original_array[c]);

        }
        printf("\n");
        printf("\n");
    }
    
    
    int size = n / world_size;
    int* sub_array=NULL;
    int* tmp_array = NULL;
    int* sorted = NULL;

    if (world_rank == 0) {

        sorted = { new int[n] {} };

    }


    if ((world_rank == 1) && (n % world_size != 0)) {
        int r = n % world_size;
        int size2 = size + r;
        sub_array = { new int[size2] {} };
        MPI_Scatter(original_array, size2, MPI_INT, sub_array, size2, MPI_INT, 0, MPI_COMM_WORLD);
        tmp_array = { new int[size2] {} };
        mergeSort(sub_array, tmp_array, 0, (size2 - 1));
        MPI_Gather(sub_array, size2, MPI_INT, sorted, size2, MPI_INT, 0, MPI_COMM_WORLD);
    }
    else {
        sub_array = { new int[size] {} };
        MPI_Scatter(original_array, size, MPI_INT, sub_array, size, MPI_INT, 0, MPI_COMM_WORLD);
        tmp_array = { new int[size] {} };
        mergeSort(sub_array, tmp_array, 0, (size - 1));
        MPI_Gather(sub_array, size, MPI_INT, sorted, size, MPI_INT, 0, MPI_COMM_WORLD);
    }

    

    

    
    if (world_rank == 0) {

        printf("Array state before final mergeSort call: ");
        for (c = 0; c < n; c++) {

            printf("%d ", sorted[c]);

        }
        
        printf("\n");

        int* other_array{ new int[n] {} };
        mergeSort(sorted, other_array, 0, (n - 1));

        printf("This is the sorted array: ");
        for (c = 0; c < n; c++) {

            printf("%d ", sorted[c]);

        }

        printf("\n");
        printf("\n");

        delete[] sorted;
        delete[] other_array;

    }

    delete[] original_array;
    delete[] sub_array;
    delete[] tmp_array;

    /********** Finalize MPI **********/
    MPI_Finalize();

}
梦境崩溃

TL; DR:使用偶数个元素调用流程MPI_ScatterMPI_Gather使用相同的元素调用count而不使用奇数元素

我的排序程序在数组中偶数个元素上都能正常工作

数组大小为偶数时,所有进程都将执行以下else部分:

   if ((world_rank == 1) && (n % world_size != 0)) {
        int r = n % world_size;
        int size2 = size + r;
        sub_array = { new int[size2] {} };
        MPI_Scatter(original_array, size2, MPI_INT, sub_array, size2, MPI_INT, 0, MPI_COMM_WORLD);
        tmp_array = { new int[size2] {} };
        mergeSort(sub_array, tmp_array, 0, (size2 - 1));
        MPI_Gather(sub_array, size2, MPI_INT, sorted, size2, MPI_INT, 0, MPI_COMM_WORLD);
    }
    else {
        sub_array = { new int[size] {} };
        MPI_Scatter(original_array, size, MPI_INT, sub_array, size, MPI_INT, 0, MPI_COMM_WORLD);
        tmp_array = { new int[size] {} };
        mergeSort(sub_array, tmp_array, 0, (size - 1));
        MPI_Gather(sub_array, size, MPI_INT, sorted, size, MPI_INT, 0, MPI_COMM_WORLD);
    }

但给出错误“ MPI_Gather中的致命错误:消息被截断,错误堆栈:MPI_Gather(sbuf = 0x00A2A700,scount = 4,MPI_INT,rbuf = 0x00A302C8,rcount = 4,MPI_INT,root = 0,MPI_COMM_WORLD)失败来自等级1和标记的消息-1342177184被截断;收到28个字节,但对于数组中的奇数个元素,缓冲区大小为16“。

但是,当数组的大小为奇数时,过程1执行上述if部分if and else,而其他过程执行该else部分。因此,某些进程将调用例程MPI_GatherMPI_Scatter使用不同的count这些例程应该在所有进程中都以相同的方式调用

要修复代码,您可以对其进行更改,以便所有进程都使用相同countMPI_ScatterMPI_Gather例程进行调用

通常,当输入的大小没有平均地除以进程数时,将面临与您相同的问题。为了解决这个问题,可以将添加到数组中,以便将大小除以进程数。或者可以使用MPI_Gatherv

从组中的所有流程聚集到指定位置

MPI_Scatterv

将缓冲区分散散布到通信器中的所有进程

源头可以看到:

MPI_Gatherv和MPI_ScattervMPI_Gather和MPI_Scatter的可变消息大小版本MPI_Gatherv扩展了MPI_Gather的功能,以允许来自每个进程的数据数量变化,并允许在将收集的数据放在根进程上的位置上具有一定的灵活性。它通过将count参数从单个整数更改为整数数组并提供新的参数displs(数组)来实现此目的。MPI_Scatterv以类似的方式扩展MPI_Scatter。有关使用这些例程的更多信息,将在本模块后面的应用示例中提供。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

mpi_gather,c中的2d动态数组,在信号6上退出(已终止)

在MPI_Gather(),MPI_Scatter()中,发送计数和接收计数有什么区别?

使用MPI的C程序中的分段错误

为什么我的C程序不要求选择char

为什么我在C中遇到段错误?

为什么这个C程序不能让我访问内存?

为什么我的C程序在不同的编译器中给出不同的输出?

为什么在C中实现列表时我的程序崩溃?

为什么我的C mpi程序中没有字符串?

为什么这样工作?我不明白为什么我的代码可以在C中工作

为什么我的C程序无法检测到特殊字符?

为什么我的if块无法在我的C程序中执行?

为什么我使用MPI障碍收到致命错误[c ++]

为什么这给我c中的分段错误?

为什么我的MPI并行程序打印两次?

为什么我的C程序崩溃?

为什么我的C ++程序崩溃了?

为什么我的简单C ++程序给我错误。

为什么我的MPI程序无法正常打印

为什么我的C程序比同等的C#慢?

为什么我不能运行此C程序?

为什么该程序不打印我提供的输入?(C)

为什么我的C ++程序不起作用?

为什么我的C#程序返回0?

MPI 程序运行时错误 MPI_GATHER,qsub mpijobparallel

向 MPI_Gather 传递一个不等于 sendtype 的 recvtype 的目的是什么?

为什么我的 C# 程序不能识别长度?

为什么我的 C 程序对评分点不起作用?

为什么我的并行 for 循环比 for 慢得多。在 C# 中